正则表达式()给出了不同的结果re.sub公司()

2024-05-13 02:09:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python3.4中使用Czech重音文本。在

调用^{}在重音句子上执行regex替换效果很好,但是使用用^{}编译的regex然后调用^{}失败。在

在这里,我对^{}^{}使用相同的参数

import re

pattern = r'(?<!\*)(Poplatn[ií]\w+ da[nň]\w+)'
flags = re.I|re.L
compiled = re.compile(pattern, flags)
text = 'Poplatníkem daně z pozemků je vlastník pozemku'
mark = r'**\1**' # wrap 1st matching group in double stars

print(re.sub(pattern, mark, text, flags))
# outputs: **Poplatníkem daně** z pozemků je vlastník pozemku
# substitution works

print(compiled.sub(mark, text))
# outputs: Poplatníkem daně z pozemků je vlastník pozemku
# substitution fails

我认为原因是重音,因为对于非重音句子^{}和{a4}的作用是相同的。在

但在我看来,这就像一个bug,因为传递相同的参数会返回不同的结果,这是不应该发生的。此主题因不同的平台和区域设置而变得复杂,因此可能无法在您的系统上重现。这是我的控制台截图。在

Python console

你在我的代码中看到了什么错误吗,还是我应该把它当作bug来报告?在


Tags: textreregex句子flagspatternmarkdan
2条回答

作为Padraic Cunningham figured out,这实际上不是一个bug。在

然而,它与一个你没有遇到的bug有关,也与你使用了一个你可能不应该使用的标志有关,所以我将在下面留下我先前的答案,即使他是你问题的正确答案。在


最近有一个ish变化(介于3.4.1和3.4.3之间,以及2.7.3和2.7.8之间)影响了这一点。在这种改变之前,你甚至不能在不引发OverflowError的情况下编译该模式。在

更重要的是,为什么要使用re.Lre.L机制并不意味着“对我的语言环境使用Unicode规则”,它意味着“使用一些未指定的非Unicode规则,这些规则只对拉丁语1派生的语言环境有意义,并且可能无法在Windows上正常工作”。或者,正如the docs所说:

Make \w, \W, \b, \B, \s and \S dependent on the current locale. The use of this flag is discouraged as the locale mechanism is very unreliable, and it only handles one “culture” at a time anyway; you should use Unicode matching instead, which is the default in Python 3 for Unicode (str) patterns.

请参阅bug #22407和链接的python dev线程,以了解最近对此的一些讨论。在

如果我去掉re.L标志,代码现在在3.4.1上编译得很好。(我在3.4.1和3.4.3中也得到了“正确”的结果,但这只是一个巧合;我现在故意不在第一个版本中传递扭曲的标志,并在第二个版本中不小心传递了扭曲的标志并将其搞砸,所以它们匹配…)

所以,即使这是一个bug,也很有可能关闭WONTFIX。22407的解决方案是在3.5中不推荐使用非bytes模式的re.L,并在3.6中将其删除,因此我怀疑现在是否有人会关心用它修复bug。(更不用说,理论上,re本身正逐渐走向有利于^{}的几十年……而IIRC,regex也反对使用bytes模式和re兼容模式。)

编译中的最后一个参数是flags,如果在re.sub中实际使用flags=flags,您将看到相同的行为:

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公司(pattern,repl,string,count=0,flags=0)

重新编译(模式,标志=0)

相关问题 更多 >