re模块中的正则表达式是否支持单词边界(\b)?

132

在尝试学习更多关于正则表达式的知识时,一个教程建议使用\b来匹配单词边界。然而,在Python解释器中运行的以下代码片段未能按预期工作:

>>> x = 'one two three'
>>> y = re.search("\btwo\b", x)

如果有任何匹配,它应该是一个匹配对象,但它却是None

\b表达式在Python中不支持吗,还是我使用错误了?


38
这个会起作用:re.search(r"\btwo\b", x) - Bolo
5
你为什么不使用“原始”字符串?r"\btwo\b" - S.Lott
4
人们常常对\b感到困惑。 - tchrist
2
是的,Python可以做到,你只需要使用原始字符串 r'\b' 来转义该字符。(否则就要双重转义 \\b,这很麻烦) - smci
5个回答

117

你的代码中应该使用原始字符串

>>> x = 'one two three'
>>> y = re.search(r"\btwo\b", x)
>>> y
<_sre.SRE_Match object at 0x100418a58>
>>> 

另外,为什么不尝试一下

word = 'two'
re.compile(r'\b%s\b' % word, re.I)

输出:

>>> word = 'two'
>>> k = re.compile(r'\b%s\b' % word, re.I)
>>> x = 'one two three'
>>> y = k.search( x)
>>> y
<_sre.SRE_Match object at 0x100418850>

1
@darren:看看我上一个例子,它只是在你所做的基础上进行了改进。我提供了原始字符串进行搜索。 - pyfunc
1
啊,经过你和Bolo的建议,问题出在我没有使用原始字符串。谢谢! - D.C.
@darren:我在13分钟前提供了这个答案 :) - pyfunc
10
-1: 倒序。应该先给出原始字符串。使用字符串替换构建re表达式的其他业务是一个不相关的坏方向,与这个特定问题无关。 - S.Lott
2
回答不好。代码可以运行,但是没有任何解释。 - Aran-Fey
显示剩余2条评论

108

这个可以正常工作:re.search(r"\btwo\b", x)

在Python中,当你写"\b"时,它是一个单字符:"\x08"。你需要转义反斜杠像这样:

"\\b"

或者像这样编写原始字符串:

r"\b"

4
这真的帮了我很多......我一直在苦恼pyspark rlike正则表达式,而且不知道为什么\b(单词边界)不起作用。谢谢。 - jb1t
谢谢,我也被这个问题困扰了。但是为什么\d不需要原始字符串就可以正常工作,而\b却不行呢? - Quinn Comendant
双反斜杠的观察真的让我摆脱了困境。谢谢。 - dimButTries
@QuinnComendant 因为\d不是转义序列,请参考 https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals 上的表格。 - user1556435

25

为了明确解释为什么re.search("\btwo\b", x)无法正常工作,这是因为Python字符串中的\b是换行符的简写。

print("foo\bbar")
fobar

因此,模式"\btwo\b"正在查找一个退格符,后跟two,再后跟另一个退格符。在您搜索的字符串x ='one two three'中没有这样的字符串。

为了让re.search(或compile)将序列\b解释为单词边界,可以转义反斜杠("\\btwo\\b")或使用原始字符串来创建模式(r"\btwo\b")。


10

Python 文档

https://docs.python.org/2/library/re.html#regular-expression-syntax

\b

匹配空字符串,但仅限于单词的开头或结尾。单词被定义为由字母数字或下划线字符组成的序列,因此单词的结尾由空格或非字母数字、非下划线字符表示。请注意,形式上,\b 被定义为 \w 和 \W 字符(或反之)或 \w 和字符串开始/结束之间的边界,因此被认为是字母数字的精确字符集取决于 UNICODE 和 LOCALE 标志的值。例如,r'\bfoo\b' 匹配 'foo','foo.','(foo)','bar foo baz',但不匹配 'foobar' 或 'foo3'。在字符范围内,\b 代表退格字符,以与 Python 字符串文字兼容。


-1

注意,对于动态变量,这种方法不起作用。

x = 'one two three'
dy = "two"
y = re.search(r"\b" + dy + "\b", x)
print(y) # None

在左右两边使用 r"\b"

x = 'one two three'
dy = "two"
y = re.search(r"\b" + dy + r"\b", x)
print(y) # <re.Match object; span=(4, 7), match='two'>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接