我使用Python 3.4中的Czech重音文本。
调用re.sub()
通过正则表达式对重音句子执行替换效果很好,但使用使用re.compile()
编译的正则表达式然后调用regex.sub()
会失败。
就是这种情况,我对re.sub()
和regex.sub()
使用相同的参数
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
我认为原因是重音,因为非重音句re.sub()
和regex.sub()
的作用相同。
但在我看来,这似乎是一个错误,因为传递相同的参数会返回不同的结果,这不应该发生。此主题因不同的平台和区域设置而变得复杂,因此在您的系统上可能无法重现。这是我的控制台的截图。
您是否在我的代码中看到任何错误,或者我应该将其作为错误报告?
答案 0 :(得分:14)
作为Padraic Cunningham figured out,这实际上并不是一个错误。
然而,与相关是一个你没有遇到过的错误,并且你使用的标志你可能不应该使用,所以我会这样做留下我之前的答案,即使他是你问题的正确答案。
最近的变化(介于3.4.1和3.4.3之间,介于2.7.3和2.7.8之间)影响了这一点。在此更改之前,您甚至无法编译该模式而不会引发OverflowError
。
更重要的是,您为什么使用re.L
? re.L
机制并不意味着&#34;对我的语言环境使用Unicode规则&#34;,它意味着&#34;使用一些未指定的非Unicode规则,这些规则只对Latin-1派生的语言环境有意义并且可能无法在Windows&#34;上正常工作。或者,正如the docs所说:
根据当前区域设置,
\w
,\W
,\b
,\B
,\s
和\S
。 不鼓励使用此标志,因为语言环境机制非常不可靠,并且它一次只能处理一个“文化”;你应该使用Unicode匹配,这是Python 3中用于Unicode(str)模式的默认设置。
请参阅bug #22407和链接的python-dev线程,以了解最近对此的一些讨论。
如果我删除re.L
标志,现在代码在3.4.1上编译就好了。 (我也得到了3.4.1和3.4.3的&#34;对&#34;结果,但这只是一个巧合;我现在故意没有通过螺旋旗并拧紧它在第一个版本中,仍然不小心没有通过螺旋旗并在第二个中拧紧它,所以它们匹配......)
所以,即使这是一个错误,也很有可能会关闭WONTFIX。 #22407的解决方案是弃用re.L
替换3.5中的非bytes
模式并将其删除3.6,所以我怀疑任何人现在都不关心修复错误。 (更不用说re
本身在理论上有利于regex
这些年中的一个......而且IIRC,regex
也弃用了L
旗帜,除非你&#39;重新使用bytes
模式和re
- 兼容模式。)
答案 1 :(得分:10)
编译中的最后一个参数是flags
,如果您在flags=flags
中实际使用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(pattern,repl,string,count = 0,flags = 0)
re.compile(pattern,flags = 0)