以普通英语列出的项目的正则表达式

这是一个人为的例子,但我试图在这里得到一个一般原则。

鉴于使用这种列表形式的英文用英文书写:

I have a cat
I have a cat and a dog
I have a cat, a dog, and a guinea pig
I have a cat, a dog, a guinea pig, and a snake

我可以使用正则表达式来获取所有项目,无论有多少项? 请注意,这些项目可能包含多个单词。

显然,如果我只有一个,那么我可以使用I have a (.+) ,如果有两个, I have a (.+) and a (.+)作品。

但是如果我想要匹配的不仅仅是一个例子,事情会变得更加复杂。 如果我想从前两个例子中提取列表项,我会认为这会起作用: I have a (.*)(?: and a (.*))? 虽然这对第一句话有用,但告诉我我有一只cat并且为null ,因为第二句告诉我我有一只cat and a dog并且为null 。 当我尝试以更多形式匹配短语时,情况只会变得更糟。

有什么方法可以使用正则表达式来达到这个目的吗? 这似乎很简单,我不明白为什么我的正则表达式匹配2项目列表的作品,但匹配1或2项目列表的匹配项没有。


您可以使用非捕获组作为条件分隔符(逗号或行尾):
' a (.*?)(?:,|$)'

python中的示例:

import re
line = 'I have a cat, a dog, a guinea pig, and a snake'
mat = re.findall(r' a (.*?)(?:,|$)', line)
print mat # ['cat', 'dog', 'guinea pig', 'snake']

我使用正则表达式分割来完成它。 但是,这假定句子格式与您的输入集完全匹配:

>>> SPLIT_REGEX = r', |I have|and|, and'
>>> for sample in ('I have a cat', 'I have a cat and a dog', 'I have a cat, a dog, and a guinea pig', 'I have a cat, a dog, a guinea pig, and a snake'):
...     print [x.strip() for x in re.split(SPLIT_REGEX, sample) if x.strip()]
... 
['a cat']
['a cat', 'a dog']
['a cat', 'a dog', 'a guinea pig']
['a cat', 'a dog', 'a guinea pig', 'a snake']

你可以做的是用find方法使用G锚点:

(?:G(?!A)(?:,? and|,)|bI have) an? ((?>[b-z]+|Ba|a(?!ndb))+(?> (?>[b-z]+|Ba|a(?!ndb))+)*)

或更简单:

(?:G(?!A)(?:,? and|,)|bI have) an? ((?!andb)[a-z]+(?> (?!andb)[a-z]+)*)

G是最后一场比赛之后的字符串中的位置。 该模式有两个入口点。 第一个匹配将使用第二个入口点: bI have和下一个匹配的第一个入口点只允许连续的结果。

注意: G表示匹配上次匹配后的位置,但它也匹配字符串的开头。 (?!A)是为了避免这种情况。

在线演示

正则表达式的行星(点击Java按钮)

链接地址: http://www.djcxy.com/p/22115.html

上一篇: Regular expression for items listed in plain english

下一篇: Trigger events on content