Python正则表达式中使用\w无效。

3
我希望有一个正则表达式,如果有两个单词,则查找短语及其前面的两个单词。例如,我有以下字符串(每行一个句子):
Chevy is my car and Rusty is my horse. My car is very pretty my dog is red.
如果使用以下正则表达式:
re.finditer(r'[\w+\b|^][\w+\b]my car',txt)

I do not get any match.

If I use the regex:

re.finditer(r'[\S+\s|^][\S+\s]my car',txt)

我得到了:'s my car' 和 '. My car' (我忽略大小写并使用多行)
为什么正则表达式 \w+\b 找不到任何内容?它应该找到两个单词和 'my car'。
如果有两个单词在 'my car' 之前,我该如何获得这两个完整的单词?如果在 my car 之前只有一个单词,则应该得到该单词。如果没有任何单词在其前面,那么我应该只得到 'my car'。在我的字符串示例中,我应该得到:'Chevy is my car' 和 'My car'(这里没有前置单词)。

请展示您正在使用的确切Python调用。 - Daniel Roseman
1个回答

7
在你的r'[\w+\b|^][\w+\b]my car正则表达式中,[\w+\b|^]匹配一个符号,这个符号可以是一个单词字符、加号(+)、退格符、管道符(|)或者脱字符(^),而[\w+\b]匹配一个符号,这个符号可以是一个单词字符或者加号或者退格符。
重点是在字符类中,量词和许多特殊字符(但不是全部)都会匹配字面符号。例如[+]匹配加号,[|^]匹配管道符或者脱字符。由于您想要匹配一个序列,因此需要在字符类之外提供一组子模式来匹配。
看起来你想使用\b作为单词边界,然而,在字符类内部,\b只匹配退格字符。
为了找到两个单词和"my car",你可以使用如下方式:
\S+\s+\S+\s+my car

请查看正则表达式演示(这里,\S+匹配一个或多个非空格符号,\s+匹配1个或多个空格符号,这两个连续的子模式的2个出现次数将这些符号作为序列匹配)。
要使my car前面的序列可选,只需使用{0,2}量词,如下所示:
(?:\S+[ \t]+){0,2}my car

参见此正则表达式演示(需使用re.IGNORECASE标志)。请参见Python演示

import re
txt  = 'Chevy is my car and Rusty is my horse.\nMy car is very pretty my dog is red.'
print(re.findall(r'(?:\S+[ \t]+){0,2}my car', txt, re.I))

详情:

  • (?:\S+[ \t]+){0,2} - 匹配0到2个由1个或多个非空白字符后跟1个或多个空格或制表符组成的序列(您也可以将其替换为[^\S\r\n]以匹配任何水平空格或\s,如果您还打算匹配换行符)。
  • my car - 一个字面文本my car

但是要注意,在正则表达式 [^|] 中,插入符号 确实 有一个特殊的含义,尽管不同 - 它使字符类匹配任何不在该类中的字符(例如,在这种情况下除了 | 字符之外的任何字符)... - Tim Pietzcker
@TimPietzcker:是的,实际上,那部分应该在SO文档中进行描述。不过,目前还没有这样的解释。 - Wiktor Stribiżew
我想问一下,为什么\b在单词“之间”时的行为不如预期,您是否可以详细说明一下。但是由于似乎是由OP作为“随机插入代码直到其正常运行”的例程之一添加的,所以我将放弃它... - Jongware
如果我逐句处理,则建议的正则表达式可以正常工作。但是,如果我使用包含多行文本并在不同位置出现'my car'的字符串执行正则表达式,则无法正常工作。我需要将“序列开始”设置为选项。这个正则表达式r'(\S+\s+|^){0,2}my car'似乎可以更好地解决问题。 - andreSmol
也许re.findall(r'(?:\S+[ \t]+){0,2}my car', txt, re.I)?完全放弃^,使用更简单的[ \t]字符类来避免匹配换行符。 - Wiktor Stribiżew
显示剩余2条评论

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