我正在用Python3在Python 2下开发的代码上运行我的单元测试套装。所有的单元测试都是在Python2下通过的,但对于Python3却没有。re的实现似乎有了一些变化,这对我来说真是太麻烦了。下面是一个复制我的问题的最小的工作示例:
Python 2.7.6 (default, Dec 10 2013, 20:01:46)
>>> import re
>>> a = re.compile('test', re.IGNORECASE)
>>> assert a.flags == re.IGNORECASE
>>> # No output, i.e. assertion passed
>>> a.flags
2
>>> re.IGNORECASE
2Python 3.3.3 (default, Dec 10 2013, 20:13:18)
>>> import re
>>> a = re.compile('test', re.IGNORECASE)
>>> assert a.flags == re.IGNORECASE
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> a.flags
34
>>> re.IGNORECASE
2显然发生了一些我不希望发生的事情!我假设有一组默认标志可以使flags在python3中为34。我想知道的是这些是什么,这样我就可以通过与适当的标志进行比较来传递我的断言。作为奖励,这样做的目的是什么?
发布于 2014-01-17 05:32:50
下面是Python3.x中的RegEx标志。
import re
print (re.IGNORECASE)
print (re.LOCALE)
print (re.MULTILINE)
print (re.DOTALL)
print (re.UNICODE)
print (re.VERBOSE)
print (re.DEBUG)
print (re.A)输出
2
4
8
16
32
64
128
256从docs,
字符串是Unicode代码点的不可变序列。
因此,默认情况下启用了re.UNICODE标志。既然您已经启用了re.IGNORECASE,那就是带有re.UNICODE的ORed,这就给了您34。
发布于 2014-01-17 05:28:47
这是因为在Python3中,字符串是unicode,因此默认情况下UNICODE标志是有意义的。
Python 3:
>>> a = re.compile("a")
>>> a.flags
32
>>> [k for k in dir(re) if getattr(re, k) == 32]
['U', 'UNICODE']发布于 2014-01-17 05:30:49
在深入研究了re源代码之后,我在“sre_parse.py”中找到了以下内容:
def fix_flags(src, flags):
# Check and fix flags according to the type of pattern (str or bytes)
if isinstance(src, str):
if not flags & SRE_FLAG_ASCII:
flags |= SRE_FLAG_UNICODE # <===== LOOK AT THIS LINE!!!!!
elif flags & SRE_FLAG_UNICODE:
raise ValueError("ASCII and UNICODE flags are incompatible")
else:
if flags & SRE_FLAG_UNICODE:
raise ValueError("can't use UNICODE flag with a bytes pattern")
return flags如果未添加"UNICODE“标志,则为您添加。它的值是SRE_FLAG_UNICODE == 32,所以是2 | 32 == re.IGNORECASE | re.UNICODE == 34。
这个函数在python2.x的实现中不存在。
https://stackoverflow.com/questions/21178424
复制相似问题