专栏首页python3同样是Python,Python3和P

同样是Python,Python3和P

上周,我的测试同事告诉我,你的用户名怎么还允许中文啊?当时我心里就想,你们测试肯定又搞错接口了,我用的是正则w过滤了参数,怎么可能出错,除非Python正则系统出错了,那是不可能的。本着严谨的作风,我自己先测试一下,没问题看我怎么怼回去。可是当我测试,我就懵逼了,中文真TM都验证通过,不对啊,我以前也是这么过滤参数的,测试没问题啊?唯一的区别是现在用的是Python3。 上网搜了一圈,发现没有一篇文章讲述Python2和Python3的正则在处理字符串是的区别,都是一视同仁,知道我去翻了一遍官方文档,才明白怎么回事。

问题复现

我们都知道,Python有个正则规则\w,几乎所有的网上博客文章都告诉你,这个规则匹配字母数字及下划线,但实际并不是这样: 有Python2代码如下:

~|⇒ pythonPython 2.7.10 (default, Aug 17 2018, 19:45:58)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.0.42)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import re>>> aa = '捕蛇者说'>>> re.match('\w{1,20}', aa)>>> bb = 'abc123ADB'>>> re.match('\w{1,20}', bb)
<_sre.SRE_Match object at 0x1031b0b28>

我们可以看到,在python2中,\w是无法匹配中文的。那么,同样的代码在Python3中运行结果是什么样子的了?

~|⇒ python3Python 3.7.1 (default, Nov 28 2018, 11:55:14)
[Clang 9.0.0 (clang-900.0.39.2)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import re>>> aa = '捕蛇者说'>>> re.match('\w{1,20}', aa)
<re.Match object; span=(0, 4), match='捕蛇者说'>>>> bb = 'abc123ADB'>>> re.match('\w{1,20}', bb)
<re.Match object; span=(0, 9), match='abc123ADB'>

但在Python3中\w是可以匹配中文的,这是怎么回事了?要回答这个问题,我们要回到Python官方文档中来寻找答案。

解决问题

当我们仔细阅读Python的官方文档时,就会发现,对于同样的正则规则\w,Python2和Python3区别好大,我们先来看看Python2:

When the LOCALE and UNICODE flags are not specified, matches any alphanumeric character and the underscore; this is equivalent to the set [a-zA-Z0-9_]. With LOCALE, it will match the set [0-9_] plus whatever characters are defined as alphanumeric for the current locale. If UNICODE is set, this will match the characters [0-9_] plus whatever is classified as alphanumeric in the Unicode character properties database.

翻译一下:当没有设置LOCALE(re.L)和UNICODE(re.U)标志,匹配数字字母和下划线,如果设置了LOCALE(re.L)则匹配数字下划线和LOCALE文字。如果设置了UNICODE(re.U)标志,匹配数字下划线和Unicode字符集里的字符。

那么Python3了:

对于 Unicode (str) 样式:
匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,也包括数字和下划线。如果设置了 ASCII 标志,就只匹配 [a-zA-Z0-9_] 。
对于8位(bytes)样式:
匹配ASCII字符中的数字和字母和下划线,就是 [a-zA-Z0-9_] 。如果设置了 LOCALE 标记,就匹配当前语言区域的数字和字母和下划线。

到此,我明白了,默认情况下,不设置任何标志,Python2 w匹配ASCII字符集里的字符,包括数字字符和下划线,Python3 w匹配数字下划线和Unicode字符集。所以,为了迁移方便,如果你想匹配ASCII字符集里的字符,指定标志为re.A,如果你想匹配Unicode字符集里的字符,指定标志为re.U。

总结

到此,我的问题是彻底解决了,但也有两个教训:

  • 看网上的教程要多注意,特别是教程里的环境和自己环境的区别
  • 多看官方文档

关于Python2和Python3,还有很多区别,这里就不一一列举了,欢迎大家留言讨论。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python 历险记(六)— pytho

    刚接触正则表达式,我也曾被它们天书似的符号组合给吓住,但经过一段时间的深入学习,发现它并没有想象中那么可怕,只要多实践,多理解,也是可以轻松搞定的。 而且我发...

    py3study
  • Python中的正则表达式

    句点(.)符号匹配除了换行符\n以外的任何字符。无论字母、数字、空格(不包括\n换行符)、可打印字符、不可打印字符,使用.都可以匹配。

    py3study
  • python 之 re

      匹配 变长的字符,在正则表达式中,用*表示任意个字符(包括0),+表示至少一个字符,用?表示0个或者1个字符  {n},表示n个字符,{n,m}表示n-m个...

    py3study
  • 简单的正则表达式

    特殊字符 ^ $ * ? + {2} {2,} {2,5} | [] [^] [a-z] . \s \S \w \W [\u4E00-\u9FA5] ...

    听城
  • python爬虫学习三:python正则

    自己写的一个爬虫:https://github.com/qester/wordpres_Crawler

    py3study
  • python re模块 正则表达式

    正则表达式对字符串的逻辑操作,主要是对字符串的一种过滤,用“元字符” 与“普通字符”组成一个字符串规则对已知的字符串或文本过滤出自己想要的字符串

    py3study
  • 浅谈Storm流式处理框架

    http://blog.csdn.net/fanyun_01/article/details/50921678

    bear_fish
  • 快速认识实时计算系统 Storm

    Storm是什么 Storm 是一个分布式数据流处理系统,用于大规模数据的实时处理。 例如用户在购物网站中会产生很多行为记录,如浏览、搜索感兴趣的商品,就可以使...

    dys
  • 【前端词典】Vue 响应式原理其实很好懂

    这是十篇 Vue 系列文章的第三篇,这篇文章我们讲讲 Vue 最核心的功能之一:响应式原理。

    小生方勤
  • 干货 | 一致性算法与区块链基础设施建设(附PPT)

    本讲座选自清华-青岛数据科学研究院大数据基础设施研究中心特约研究员、加拿大Viscore公司创始人兼总裁刘运渠先生于近期在清华大数据“技术·前沿”系列讲座上所做...

    数据派THU

扫码关注云+社区

领取腾讯云代金券