sim*_*rsh 0 python regex regex-negation
我必须匹配文本中的所有字母数字单词.
>>> import re
>>> text = "hello world!! how are you?"
>>> final_list = re.findall(r"[a-zA-Z0-9]+", text)
>>> final_list
['hello', 'world', 'how', 'are', 'you']
>>>
Run Code Online (Sandbox Code Playgroud)
这很好,但是我还有一些词可以否定,即不应该在我的最终列表中的词.
>>> negate_words = ['world', 'other', 'words']
Run Code Online (Sandbox Code Playgroud)
这是一个糟糕的方式
>>> negate_str = '|'.join(negate_words)
>>> filter(lambda x: not re.match(negate_str, x), final_list)
['hello', 'how', 'are', 'you']
Run Code Online (Sandbox Code Playgroud)
但是如果可以改变我的第一个正则表达式模式以考虑否定这些单词,我可以保存一个循环.我发现对字符的否定,但我有言辞否定,我也在其他问题中找到正则表达式,但这也无济于事.
可以使用python re完成吗?
更新
我的文字可以跨越几条线条.此外,negate_words列表也可能很长.
考虑到这一点,正在使用正则表达式来完成这样的任务,首先纠正?有什么建议??
我不认为使用正则表达式有一种干净的方法.我能找到的最接近的地方有点丑陋而且不完全是你想要的:
>>> re.findall(r"\b(?:world|other|words)|([a-zA-Z0-9]+)\b", text)
['hello', '', 'how', 'are', 'you']
Run Code Online (Sandbox Code Playgroud)
为什么不使用Python的集合呢?它们非常快:
>>> list(set(final_list) - set(negate_words))
['hello', 'how', 'are', 'you']
Run Code Online (Sandbox Code Playgroud)
如果订单很重要,请参阅下面的@glglgl回复.他的列表理解版本非常易读.这是使用itertools的快速但不太可读的等价物:
>>> negate_words_set = set(negate_words)
>>> list(itertools.ifilterfalse(negate_words_set.__contains__, final_list))
['hello', 'how', 'are', 'you']
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用re.finditer在单个传递中构建单词列表:
>>> result = []
>>> negate_words_set = set(negate_words)
>>> result = []
>>> for mo in re.finditer(r"[a-zA-Z0-9]+", text):
word = mo.group()
if word not in negate_words_set:
result.append(word)
>>> result
['hello', 'how', 'are', 'you']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2279 次 |
| 最近记录: |