Python regex.sub()为re.sub()提供了不同的结果
我在Python 3.4中使用重音文本 调用regex对重音句子执行替换效果很好,但使用用编译的regex然后调用失败 在这里,我对和使用相同的参数Python regex.sub()为re.sub()提供了不同的结果,python,regex,python-3.x,Python,Regex,Python 3.x,我在Python 3.4中使用重音文本 调用regex对重音句子执行替换效果很好,但使用用编译的regex然后调用失败 在这里,我对和使用相同的参数 重新导入 pattern=r'(?As,这实际上不是一个bug 然而,它与一个你没有遇到的bug有关,与你使用了一个你可能不应该使用的标志有关,所以我将在下面留下我先前的答案,即使他是你问题的正确答案 最近有一个ish更改(介于3.4.1和3.4.3之间,以及介于2.7.3和2.7.8之间)影响了这一点。在该更改之前,您甚至无法编译该模式而不引发
重新导入
pattern=r'(?As,这实际上不是一个bug
然而,它与一个你没有遇到的bug有关,与你使用了一个你可能不应该使用的标志有关,所以我将在下面留下我先前的答案,即使他是你问题的正确答案
最近有一个ish更改(介于3.4.1和3.4.3之间,以及介于2.7.3和2.7.8之间)影响了这一点。在该更改之前,您甚至无法编译该模式而不引发溢出错误
更重要的是,为什么要使用re.L
?re.L
机制并不意味着“对我的语言环境使用Unicode规则”,而是意味着“使用一些未指定的非Unicode规则,这些规则只对拉丁语派生的语言环境有意义,并且可能无法在Windows上正常工作”。或者,正如所说:
使\w
,\w
,\b
,\b
,\s
和\s
依赖于当前区域设置。不鼓励使用此标志,因为区域设置机制非常不可靠,并且它只处理一个“区域性”无论如何,每次都应该使用Unicode匹配,这是Python3中Unicode(str)模式的默认设置
有关这方面的一些最新讨论,请参阅和链接的python开发线程
如果我去掉re.L
标志,代码现在在3.4.1上编译得很好。(我也得到了“正确的”3.4.1和3.4.3上的结果,但这只是巧合;我现在故意不在第一个版本中传递扭曲的标志并将其拧紧,但仍然意外地没有在第二个版本中传递扭曲的标志并将其拧紧,因此它们匹配……)
因此,即使这是一个bug,它也很有可能在WONTFIX中被关闭。#22407的解决方案是在3.5中反对re.L
非bytes
模式,并在3.6中删除它,所以我怀疑现在是否有人会在意用它修复bug。(更不用说,re
本身在理论上正走向这几十年中的一个……而IIRC,regex
也不赞成使用L
标志,除非您使用的是bytes
模式和re
兼容模式。)编译中的最后一个参数是标志
,如果您在re.sub
中实际使用标志=标志
,您将看到相同的行为:
compiled = re.compile(pattern, flags)
print(compiled)
text = 'Poplatníkem daně z pozemků je vlastník pozemku'
mark = r'**\1**' # wrap 1st matching group in double stars
r = re.sub(pattern, mark, text, flags=flags)
re.sub
的第四个参数是count
,这就是您看到差异的原因
re.sub(模式、应答、字符串、计数=0、标志=0)
重新编译(模式,标志=0)这很可能是一个bug-我可以在Windows 7上的空闲3.4.1上复制它,并期望这两种表单的输出相同。当我在自制的3.4.1上尝试这一点时,我发现溢出错误:在重新编译
行中,正则表达式代码大小超过了限制。与python.org中的3.3.2相同,并且(在添加了u
前缀后)MacPorts的2.7.3。但是3.5alpha主干和3.4树的本地版本,以及Apple的2.7.6,都可以正常工作。这意味着在这个模式中有一个相当新的错误修复,这使得看起来更可能仍然有一个错误潜伏在那里…(我建议搜索最近的错误修复程序,以便您可以在新的错误中链接到它。)更改.sub()
调用的顺序会改变什么吗?@user3012759问得好!但不会。等等……为什么您首先要使用re.L
?对于Unicode模式,它的作用并没有超出定义范围“您不应该使用它”,但它是(在CPython中)实现的就像一些你几乎永远不会想要的时髦的拉丁语-1特定规则,尤其是东欧文本中的规则。通过快速测试,如果删除该标志,它将修复3.4.1中的异常,并修复3.4.3中不正确的结果。太棒了!但是描述有点混乱。他已经知道compile
中的大参数是flags
;问题是sub
的第四个参数不是flags
,而是count
。因此,他实际上传递的是count=6,flags=0
(这就是为什么当有多个关键字参数时,您应该始终使用关键字参数的原因。)@abarnert,是的,他忘了添加那部分。干杯。有趣的是,他实际上有两个bug相互抵消。这是第一个,他不小心将标志
传递为计数
,返回他想要的结果,因为这防止了re.L
标志破坏东西……哎哟,我怎么没发现呢!啊然而,正是出于这个原因,这样对参数进行排序似乎有点愚蠢。@jornsharpe:IIRC,flags
在原始的(s)re
模块中不存在。当它在2.3左右版本中添加时,唯一合理的做法是在所有现有参数之后将其添加到每个函数中。(好吧,真正合理的做法是将其设置为仅限关键字的参数,但当时没有人这么想。)感谢您的帮助。re.sub()
中的参数顺序错误导致了re.sub()
和regex.sub()之间的结果不同
和有争议的re.L
标志导致模式不匹配。这个糟糕的巧合让我困惑,你的解释治好了我的头痛。
compiled = re.compile(pattern, flags)
print(compiled)
text = 'Poplatníkem daně z pozemků je vlastník pozemku'
mark = r'**\1**' # wrap 1st matching group in double stars
r = re.sub(pattern, mark, text, flags=flags)