11

我正在尝试在单词列表中定位字符串的所有索引位置,并且我希望将值作为列表返回。如果它是单独的,或者它是否在标点符号之前或之后,我想找到该字符串,但如果它是一个较大单词的子字符串,则不是。

以下代码仅捕获“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]

谢谢

4

2 回答 2

21

您不需要将match返回的结果分配给x. 你的比赛应该是 onx而不是list.

此外,您需要使用re.search而不是re.match,因为您的正则表达式模式'\W*myString\W*'将不匹配第一个元素。那是因为test;与 不匹配\W*。实际上,您只需要测试紧随其后的字符和前面的字符,而不是完整的字符串。

因此,您可以word boundaries在字符串周围使用:

pattern = r'\b' + re.escape(myString) + r'\b'
indices = [i for i, x in enumerate(myList) if re.search(pattern, x)]
于 2013-02-11T19:13:55.877 回答
5

您的代码存在一些问题。首先,您需要将 expr 与列表元素 ( x) 进行匹配,而不是与整个列表 ( myList) 进行匹配。其次,为了在表达式中插入变量,您必须使用+(字符串连接)。最后,使用原始文字 ( r'\W) 正确解释 expr 中的斜杠:

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)]
于 2013-02-11T19:15:52.993 回答