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

时间:2010-11-28 05:47:04

标签: python regex

试试这段代码。

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

这应该用_z

替换所有独立的z

然而,结果是:

'az _z bz _z z stuff _z _z'

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

4 个答案:

答案 0 :(得分:6)

如果您的目标是确保仅在z为独立单词时匹配\b,请使用>>> re.sub(r'\b(z)\b', r'_\1', test) ' az _z bz _z _z stuff _z _z ' 匹配单词边界,而不实际使用空格:

{{1}}

答案 1 :(得分:5)

您希望避免捕获空白。尝试使用0宽度的分词\b,如下所示:

re.sub(r'\bz\b', '_z', test)

答案 2 :(得分:4)

这样做的原因是你得到一个重叠的匹配;你需要不匹配额外的角色 - 你有两种方法可以做到这一点;一个正在使用\b,其他人使用 lookbehind断言 lookahead断言。 (如果合理,可能应该使用\b代替此解决方案。这主要用于教育目的。)

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

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

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

特殊(?...)语法表示它们不是群组,因此(z)\1


至于失败原因的图解说明:

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

' az _z bz z z stuff z  z '
          ^^^

它取代了。最后一个角色已被采取行动,所以下一步就是这样:

' az _z bz _z z stuff z  z '
              ^^^ <- It starts matching here.
             ^ <- Not this character, it's been consumed by the last match

答案 3 :(得分:1)

使用此:

test = ' az z bz z z stuff z  z '
re.sub(r'\b(z)\b', r'_\1', test)