上周,个人测试同事告诉我,你的用户名怎么还容许中文啊?当时我内心就想,大家测试确定又搞错接口了,我用的是正则w过滤了参数,怎么可能出错,除非Python正则系统出错了,那是不可能的。本着严谨的做风,我本身先测试一下,没问题看我怎么怼回去。但是当我测试,我就懵逼了,中文真TM都验证经过,不对啊,我之前也是这么过滤参数的,测试没问题啊?惟一的区别是如今用的是Python3。
上网搜了一圈,发现没有一篇文章讲述Python2和Python3的正则在处理字符串是的区别,都是一视同仁,知道我去翻了一遍官方文档,才明白怎么回事。python
咱们都知道,Python有个正则规则w
,几乎全部的网上博客文章都告诉你,这个规则匹配字母数字及下划线,但实际并非这样:
有Python2代码以下:测试
~|⇒ python Python 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 darwin Type "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中运行结果是什么样子的了?ui
~|⇒ python3 Python 3.7.1 (default, Nov 28 2018, 11:55:14) [Clang 9.0.0 (clang-900.0.39.2)] on darwin Type "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官方文档中来寻找答案。this
当咱们仔细阅读Python的官方文档时,就会发现,对于一样的正则规则w
,Python2和Python3区别好大,咱们先来看看Python2:spa
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了:code
对于 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。orm
到此,个人问题是完全解决了,但也有两个教训:教程
关于Python2和Python3,还有不少区别,这里就不一一列举了,欢迎你们留言讨论。接口
获取更多文章,关注个人公众号:littlebyte