为什么Python中的re.sub在这个测试用例中无法正常工作?

3 python regex

试试这个代码.

test = ' az z bz z z stuff z  z '
re.sub(r'(\W)(z)(\W)', r'\1_\2\3', test)
Run Code Online (Sandbox Code Playgroud)

这应该用_z替换所有独立的z

但结果是:

'az _z bz _z z stuff _z _z'

你看到那里有缺少的az.我认为这是因为分组不能同时抓住z之间的空间来匹配两个z(一个用于尾随空格,一个用于前导空格).有没有办法来解决这个问题?

Joh*_*ica 6

如果您的目标是确保只z在它是独立单词时\b匹配,请使用匹配单词边界而不实际使用空格:

>>> re.sub(r'\b(z)\b', r'_\1', test)
' az _z bz _z _z stuff _z  _z '
Run Code Online (Sandbox Code Playgroud)


Avi*_*Avi 5

你想避免捕获空白.尝试使用0宽度的分词符\b,如下所示:

re.sub(r'\bz\b', '_z', test)
Run Code Online (Sandbox Code Playgroud)


Chr*_*gan 5

这样做的原因是你得到了一个重叠的匹配;你需要不匹配额外的字符 - 有两种方法可以做到这一点;一个是使用\b词边界,正如其他人所建议的那样,另一个是使用后向断言先行断言。(如果合理,应该使用它\b来代替此解决方案。这主要用于教育目的。)

>>> re.sub(r'(?<!\w)(z)(?!\w)', r'_\1', test)
' az _z bz _z _z stuff _z  _z '
Run Code Online (Sandbox Code Playgroud)

(?<!\w)确保以前没有\w

(?!\w)确保没有\w之后。

特殊(?...)语法意味着它们不是组,因此(z)\1.


至于失败原因的图形解释:

正则表达式正在通过字符串进行替换;它在这三个字符处:

' az _z bz z z stuff z  z '
          ^^^
Run Code Online (Sandbox Code Playgroud)

它做那个替换。最后一个角色已经被执行了,所以它的下一步大约是这样的:

' az _z bz _z z stuff z  z '
              ^^^ <- It starts matching here.
             ^ <- Not this character, it's been consumed by the last match
Run Code Online (Sandbox Code Playgroud)