如何将一个负面的lookbehinds列表附加到python正则表达式?

时间:2013-01-28 08:57:08

标签: python regex

我正在尝试使用正则表达式拆分将一个段落拆分为句子,我正在尝试使用此处发布的第二个答案: a Regex for extracting sentence from a paragraph in python

但是我有一个缩写列表,即使有一段时间我也不想结束句子。但我不知道如何正确地将它附加到正则表达式。我正在阅读一个文件的缩写,其中包含像Dr. St.先生这样的术语(每行一个)。

2 个答案:

答案 0 :(得分:1)

简短的回答:你不能,除非所有的后瞻断言是相同的,固定宽度(它们可能不在你的情况下;你的例子只包含两个字母的缩写,但是Mrs.会破坏你的正则表达式。

这是当前Python正则表达式引擎的限制。

更长的答案:

可以编写一个像(?s)(?<!.Mr|Mrs|.Ms|.St)\.这样的正则表达式,根据需要用尽可能多的.填充lookbehind断言的每个交替部分,以使它们全部达到相同的宽度。但是,在某些情况下会失败,例如当段落以Mr.开头时。

无论如何,你没有在这里使用正确的工具。更好地使用专为工作设计的工具,例如Natural Language Toolkit

如果你坚持使用正则表达式(太糟糕了!),那么你可以尝试使用findall()方法而不是split()

(?:(?:\b(?:Mr|Ms|Dr|Mrs|St)\.)|[^.])+\.\s*

将匹配以.结尾的句子(可选地后跟空格)并且可以不包含任何点,除非前面有一个允许的缩写。

>>> import re
>>> s = "My name is Mr. T. I pity the fool who's not on the A-Team."
>>> re.findall(r"(?:(?:\b(?:Mr|Ms|Dr|Mrs|St)\.)|[^.])+\.\s*", s)
['My name is Mr. T. ', "I pity the fool who's not on the A-Team."]

答案 1 :(得分:1)

我没有直接回答您的问题,但是这篇文章应该包含足够的信息,可以为您的问题编写正则表达式。

可以附加一系列负面后卫。请记住,后视镜是零宽度,这意味着您可以根据需要放置尽可能多的后视镜,并且您仍然可以从同一位置看后面。只要您不需要在后台使用“很多”量词(例如*+{n,}),一切都应该没问题(?)。

所以可以像这样构造正则表达式:

(?<!list )(?<!of )(?<!words )(?<!not )(?<!allowed )(?<!to )(?<!precede )pattern\w+

有点太冗长了。无论如何,我写这篇文章只是为了证明可以在固定字符串列表上查看。

示例运行:

>>> s = 'something patterning of patterned crap patternon not patterner, not allowed patternes to patternsses, patternet'
>>> re.findall(r'(?<!list )(?<!of )(?<!words )(?<!not )(?<!allowed )(?<!to )(?<!precede )pattern\w+', s)
['patterning', 'patternon', 'patternet']

尽管如此,使用后视还是有一个问题。如果列入黑名单的文本与匹配模式的文本之间存在动态数量的空格,则上述正则表达式将失败。我真的怀疑是否存在一种修改正则表达式的方法,以便它适用于上面的情况,同时保持后视。 (您始终可以将连续的空格替换为1,但对于更一般的情况则不起作用。)