为什么此正则表达式代码在Python 2.7和Python 3.7中会有不同的结果?

时间:2019-05-26 02:42:28

标签: python regex python-2.7 python-3.7

这是为了验证用户名,我的代码:

import re
regex = r'^[\w.@+-]+\Z'
result = re.match(regex,'名字')

在python2.7中,它返回None

在python3.7中,它返回“名字”。

1 个答案:

答案 0 :(得分:4)

这是因为\wPython 2.7Python 3.7的定义不同。

Python 2.7中,我们有:

  

未指定LOCALE和UNICODE标志时,将匹配   字母数字字符和下划线; 这等同于   设置[a-zA-Z0-9_]

(添加了强调和超链接以及格式)

但是,在Python 3.7中,我们有:

  

对于Unicode(str)模式:匹配Unicode单词字符; 此   包括大多数可以是任何语言的单词组成部分的字符,   以及数字和下划线。如果使用ASCII标志,则仅   [a-zA-Z0-9_]已匹配。

(添加了强调和格式)

因此,如果您希望它在两个版本中均可工作,则可以执行以下操作:

# -*- coding: utf-8 -*-
import re
regex = re.compile(r'^[\w.@+-]+\Z', re.UNICODE)
match = regex.match(u'名字')

if match:
    print(match.group(0))
else:
    print("not matched!")

output:
名字

这里证明它在两个版本中都适用:

works

请注意区别:

  • 我在脚本的顶部添加了# -*- coding: utf-8 -*-,因为没有它,在Python 2.7中,我们会得到error的说法

      

    第3行上的非ASCII字符'\ xe5',但未声明任何编码;看到   http://www.python.org/peps/pep-0263.html了解详情

  • 不是使用result = re.match(pattern, string),而是使用regex = re.compile(pattern, flags)match = regex.match(string),以便可以指定 flags

  • 我使用了re.UNICODE标志,因为没有它,在Python 2.7中,它仅在使用[a-zA-Z0-9_]时才匹配\w

  • 我使用u'名字'代替了'名字',因为在Python 2.7中,您需要使用Unicode Literals来表示Unicode字符。

此外,在回答您的问题时,我还发现print("not matched!")中的Python 2.7 works也很有意义,因为在这种情况下,括号被忽略了,而我没有这样做。不知道,所以很有趣。