Python 3 正则表达式单词边界不明确

3
我正在使用正则表达式来查找字符串“my car”,并检测它之前的最多四个单词。我的参考文本是:
my house is painted white, my car is red.
A horse is galloping very fast in the road, I drive my car slowly.

如果我使用正则表达式:
re.finditer(r'(?:\w+[ \t,]+){0,4}my car',txt,re.IGNORECASE|re.MULTILINE)

我得到了预期的结果。例如:房子被涂成白色,我的车
如果我使用正则表达式:
re.finditer(r'(?:\w+\b){0,4}my car',txt,re.IGNORECASE|re.MULTILINE)

我只收到了:“我的车”和“我的车”,也就是说,我没有得到它之前长达四个单词的内容。为什么我不能使用\b来匹配0到4个单词组中的单词?

3
\b 是零宽断言,它不会匹配你的单词后面的空格、逗号等字符。 - anubhava
单词边界的正则表达式是 (?:(?:^|(?<=[^a-zA-Z0-9_]))(?=[a-zA-Z0-9_])|(?<=[a-zA-Z0-9_])(?:$|(?=[^a-zA-Z0-9_]))),也许你可以找到你所犯的错误。 - user557597
2个回答

2
因为\b是一个零宽断言,匹配字符串的开始和单词字符之间、非单词字符和单词字符之间、单词字符和非单词字符之间以及单词字符和字符串结尾之间的位置(不会消耗文本)(?:\w+\b){0,4}只匹配空字符串,因为在my car之前没有1个或更多的单词字符后跟一个单词边界。
相反,您可能希望匹配1个或多个非单词字符,这将有效地模拟一个单词边界:
(?:\w+\W+){0,4}my car\b

查看正则表达式演示

当然,你可以在car之后使用单词边界,以避免匹配到carriage - Wiktor Stribiżew

2

您可以使用以下方法:

(?:\b\w+\W+){4}
\b(?:my\ car)\b

请查看regex101.com上的演示


Python中,这将是:

import re

rx = re.compile(r'''
                (?:\b\w+\W+){0,4}
                \b(?:my\ car)\b
                ''', re.VERBOSE)

string = """
my house is painted white, my car is red.
A horse is galloping very fast in the road, I drive my car slowly.
"""
words = rx.findall(string)
print(words)
# ['house is painted white, my car', 'the road, I drive my car']

2
你在\w\W之间不能没有单词边界,因此,在\w+\b\W+中的\b是多余的。 - Wiktor Stribiżew
是的,根据定义,(?<=\W)(?=\w) 是一个单词边界。因此,(?:\b\w+\W+){0,4} 对于完整的 {4} 就是 \b\w+\W+\b\w+\W+\b\w+\W+\b\w+\W+。然后,\W+\b\w+ 等同于 \W+\w+ - user557597

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