如何在Python的列表推导中使用正则表达式?

12 投票
2 回答
42014 浏览
提问于 2025-04-17 15:31

我想在一个单词列表中找到一个字符串的所有索引位置,并希望返回这些位置的列表。我想找到这个字符串,无论它是单独出现,还是前面或后面有标点符号,但如果它是一个更大单词的一部分就不算。

下面的代码只捕捉到了“cow”,而漏掉了“test;cow”和“cow。”这两个。

myList = ['test;cow', 'one', 'two', 'three', 'cow.', 'cow', 'acow']
myString = 'cow'
indices = [i for i, x in enumerate(myList) if x == myString]
print indices
>> 5

我尝试把代码改成使用正则表达式:

import re
myList = ['test;cow', 'one', 'two', 'three', 'cow.', 'cow', 'acow']
myString = 'cow'
indices = [i for i, x in enumerate(myList) if x == re.match('\W*myString\W*', myList)]
print indices

但是这给了我一个错误:期望字符串或缓冲区

如果有人知道我哪里出错了,我会很高兴听到。我感觉这可能跟我在这里尝试使用正则表达式有关,而它期待的是一个字符串。有没有解决办法?

我想要的输出应该是:

>> [0, 4, 5]

谢谢

2 个回答

7

你的代码有几个问题。首先,你需要把表达式(expr)和列表中的每个元素(x)进行匹配,而不是和整个列表(myList)匹配。其次,要在表达式中插入一个变量,你需要用 + 来连接字符串。最后,使用原始字符串(r'\W')来正确处理表达式中的斜杠:

import re
myList = ['test;cow', 'one', 'two', 'three', 'cow.', 'cow', 'acow']
myString = 'cow'
indices = [i for i, x in enumerate(myList) if re.match(r'\W*' + myString + r'\W*', x)]
print indices

如果你的字符串(myString)中可能包含特殊的正则表达式字符(比如斜杠或点),你还需要对它使用 re.escape 进行处理:

regex = r'\W*' + re.escape(myString) + r'\W*'
indices = [i for i, x in enumerate(myList) if re.match(regex, x)]

正如评论中提到的,下面的选项可能会更好:

regex = r'\b' + re.escape(myString) + r'\b'
indices = [i for i, x in enumerate(myList) if re.search(regex, x)]
23

你不需要把 match 的结果再赋值给 x。而且,你的匹配应该是在 x 上,而不是在 list 上。

另外,你需要用 re.search 而不是 re.match,因为你的正则表达式 '\W*myString\W*' 不会匹配到第一个元素。这是因为 test; 这个部分不符合 \W* 的要求。实际上,你只需要检查紧接着的字符和前面的字符,而不是整个字符串。

所以,你可以在字符串周围使用 单词边界

pattern = r'\b' + re.escape(myString) + r'\b'
indices = [i for i, x in enumerate(myList) if re.search(pattern, x)]

撰写回答