正则表达式匹配句子的一部分

时间:2015-10-16 13:59:25

标签: python regex

我试图在一个否定词之后找到一个句子的一部分(例如,不要,不能),直到下一个标点符号并附上" _NOT&#34 ;在该部分句子的每个单词的末尾,例如: "我真的很喜欢火鸡,但不喜欢西红柿鸡肉,因为我过敏"变 "我真的很喜欢火鸡,但不喜欢鸡肉_NOT with_NOT tomatoes_NOT,因为我过敏"。

最初我的方法是运行看起来像这样的正则表达式:

(dont|cant|not)(.*)[!?,.]

获取我感兴趣的句子部分,然后逐字逐句地附加_NOT,然后运行 str.replace(oldPartOfSentence,newPartOfSentence)

这几乎可行,但搜索并不贪婪,如果我稍后会有一个标点符号,它会发现一个比它需要更长的句子部分。此外,如果我有一个否定词,它不支持这种情况,但它后面没有标点符号(那么它应该对从否定词到字符串结尾的每个字添加否定)。

例如,运行示例句子上的正则表达式

[('not', ' chicken with tomatoes')]

但如果我在结尾处完全停止,我会得到:

[('not', " chicken with tomatoes, because I'm allergic")]

我该如何解决这个问题,并且整体上有更有效的解决方案吗?例如,有没有办法更新正则表达式以自动附加" _NOT"在句子的末尾通过 re.sub()

1 个答案:

答案 0 :(得分:1)

根据Steven's comment,只需将.*更改为.*?即可使其变得非贪婪。

您无法使用单个正则表达式AFAICT进行替换(请参阅my comment on the question中的原因),但是一组链接替换将起作用:

def add_nots(m):
    notty, following = m.groups()
    return notty + re.sub(r'(\S+)', r'\1_NOT', following)

notted = re.sub(r'(dont|cant|not)(.*?)(?=[!?,.]|$)', add_nots, original_string)

注意:我对正则表达式进行了额外的更改以使用正向预测断言以避免捕获终止标点符号(或行尾,这是一个更改;您仅使用非贪婪修复程序提供的原始版本不会#&# 39;当符号线组件在字符串末尾结束时匹配,而不是与识别的标点符号之一结束,因此标点符号/行尾不需要由{{1}捕获和再现替换功能。

此外,如果你要做很多事情,穿插其他正则表达式,你可能想要预编译你的正则表达式对象而不是依赖sub缓存:

re