使用Python的re.sub函数查找一个单词列表中的所有单词

6

我对正则表达式不太熟悉,但我正在尝试迭代列表并使用 re.sub 从一个保存在变量 first_word 中的大块文本中取出多个项。

我首先使用 re.sub 删除标签,这很好用,但接下来我想删除 exclusionList 变量中的所有字符串,但我不确定该如何操作。

感谢您的帮助,以下是引发异常的代码。

exclusionList = ['+','of','<ET>f.','to','the','<L>L.</L>']

for a in range(0, len(exclusionList)):
      first_word = re.sub(exclusionList[a], '',first_word)

同时,还有一个异常:

first_word = re.sub(exclusionList[a], '',first_word)
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 151, in sub
return _compile(pattern, flags).sub(repl, string, count)
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 245, in _compile
raise error, v # invalid expression error: nothing to repeat

first_word = re.sub(exclusionList[a], '',first_word) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py”,第151行,sub函数: 返回_compile(pattern, flags).sub(repl, string, count) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py”,第245行,_compile函数: raise error, v # invalid expression 错误:无内容可重复 - English Grad
1
Junuxx,感谢您的帮助。我只是在exclusionList中添加了'+',现在它可以正常工作了。由于列表是静态的,所以这对我来说是一个很好的解决方案。再次感谢您的帮助。 - English Grad
2个回答

12

正则表达式中加号符号是一个操作符,表示“前面的内容出现一次或多次”。例如,x+ 表示 x 出现一次或多次。如果您想查找和替换实际的加号符号,需要像这样转义它:re.sub('\+', '', string)。因此,请更改您排除列表中的第一个条目。

您也可以像这样消除 for 循环:

exclusions = '|'.join(exclusionList)
first_word = re.sub(exclusions, '', first_word)

在正则表达式中,管道符号|表示或(disjunction),因此x|y|z匹配x或y或z。


抱歉如果我让你感到困惑了。那部分代码是正常工作的。我将其从代码中删除,以便更清楚地了解问题所在,并将异常作为注释包含在内。感谢您的帮助。 - English Grad
@EnglishGradпјҡдёҚпјҢеҠ еҸ·з¬ҰеҸ·жҳҜејӮеёёзҡ„еҺҹеӣ гҖӮе°Ҷre.sub('+', '', 'foo')дёҺre.sub('\+', '', 'foo')иҝӣиЎҢжҜ”иҫғгҖӮ第дёҖдёӘдјҡеҜјиҮҙдҪ зңӢеҲ°зҡ„ејӮеёёпјҢиҖҢ第дәҢдёӘеҲҷдёҚдјҡгҖӮ - Junuxx
Junuxx,我现在明白你在说什么了。谢谢你的帮助。 - English Grad

2
你的程序基本格式是正确的,所以我怀疑你遇到的任何问题都与你使用的正则表达式有关。加号“+”本身是无效的正则表达式,你需要使用反斜杠进行转义。

从使用角度来看,Python允许你指定一个字符串不会进行反斜杠转义,这样你就不必在想要表示“\”时将你的正则表达式中混入大量的“\\”。这个语法是在前面加上“r”,例如r'\+',这是你应该用来替换exclusionList中第一项的内容。

如果你想提取单词“to”、“the”等等,那么你还需要确保你提取的是整个单词,而不是意外提取了“tooth”中的“to”或“other”中的“the”。添加“\b”可以指定单词边界,以防止这种情况: r'\bto\b'r'\bthe\b'

最后,for a in range(0, len(exclusionList)): 可以简单地通过直接迭代列表本身来实现:for exclusion in exclusionList:


关于单词边界的观点很好,但我不同意你关于循环的建议。 - Junuxx
for a in range(0,len(seq)): do something with seq[a]这种形式有一些限制。seq必须支持len()[]访问,因此您不能传递除列表或元组之外的任何内容(集合和字典将失败-没有[],以及生成器或生成器表达式-没有len)。调用两个函数,rangelen,在2.x Python中,range实际上构建了一个包含所有值的中间列表对象。使用带有列表索引范围的for是从C或BASIC继承下来的习惯用语;迭代器更有效率,更广泛适用。 - PaulMcG
这些都是真的,但不是我想表达的。在这种情况下,for循环及其开销完全是不必要的,请参见我的答案。 - Junuxx

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