【问题标题】:How do you use a regex in a list comprehension in Python?如何在 Python 的列表推导中使用正则表达式?
【发布时间】:2013-01-26 23:15:44
【问题描述】:

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

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

谢谢

【问题讨论】:

    标签: python regex


    【解决方案1】:

    您不需要将match 的结果分配回x。你的比赛应该在x而不是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)]
    

    【讨论】:

      【解决方案2】:

      您的代码存在一些问题。首先,您需要将 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)]
      

      正如 cmets 中所指出的,以下可能是更好的选择:

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

      【讨论】:

      • 也可以加re.escape
      • @MartijnPieters:当然,添加了。
      • 这与 OP 想要匹配的第一个元素不匹配。
      • 另一个问题是正则表达式实际上并未提供 OP 期望的输出(例如,它与 test;cow 不匹配)。我认为re.search(r'\b' + myString + r'\b', x) 可能有用。
      • 谢谢。我遇到了 r'\b*' 的问题,它返回错误“没有重复”,如上面的评论中所述。
      猜你喜欢
      • 2015-10-05
      • 2013-11-24
      • 2021-05-16
      • 2015-08-02
      • 1970-01-01
      • 2015-11-06
      • 2018-09-15
      • 2019-04-01
      • 2016-09-27
      相关资源
      最近更新 更多