如何在Python的列表推导中使用正则表达式?
我想在一个单词列表中找到一个字符串的所有索引位置,并希望返回这些位置的列表。我想找到这个字符串,无论它是单独出现,还是前面或后面有标点符号,但如果它是一个更大单词的一部分就不算。
下面的代码只捕捉到了“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)]