这是一个人为的例子,但我想在这里找到一般原则。
给出使用此类列表形式的英文短语:
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
和{{1} },对于第二个,它告诉我我有一个null
和cat and a dog
。当我尝试以更多形式匹配短语时,情况会变得更糟。
我有什么办法可以为此目的使用正则表达式吗?这似乎相当简单,我不明白为什么我的正则表达式匹配2项目列表,但匹配1或2项目列表的正则表达不起作用。
答案 0 :(得分:1)
您可以将非捕获组用作条件分隔符(逗号或行尾):
' 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']
答案 1 :(得分:1)
我使用正则表达式拆分来完成它。但这假设句子格式与您的输入集完全匹配:
>>> 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']
答案 2 :(得分:1)
您可以使用\G
方法使用find
锚点:
(?:\G(?!\A)(?:,? and|,)|\bI have) an? ((?>[b-z]+|\Ba|a(?!nd\b))+(?> (?>[b-z]+|\Ba|a(?!nd\b))+)*)
或更简单:
(?:\G(?!\A)(?:,? and|,)|\bI have) an? ((?!and\b)[a-z]+(?> (?!and\b)[a-z]+)*)
\G
是最后一次匹配后字符串中的位置。该模式有两个入口点。第一个匹配将使用第二个入口点:\bI have
,然后匹配,第一个入口点只允许连续的结果。
注意:\G
表示匹配最后一次匹配后的位置,但它也匹配字符串的开头。 (?!\A)
是为了避免这种情况。
regex planet (点击Java按钮)
答案 3 :(得分:0)
使用正向前瞻性regexp提供一个java实现。见下文:
String str0 = "I have a cat";
String str1 = "I have a cat and a dog";
String str2 = "I have a cat, a dog, and a guinea pig";
String str3 = "I have a cat, a dog, a guinea pig, and a snake";
String regexp = "(?m)\\ba\\s+.*?(?=(?:,|$|and))";
Pattern pMod = Pattern.compile(regexp);
Matcher mMod = pMod.matcher(str3);
while (mMod.find()) {
System.out.println(mMod.group(0));
}
对于str3,输出为:
a cat
a dog
a guinea pig
a snake
如果该项目可以是'a','an'或'one',那么正则表达式可以是(?m)\\b(one|an|a)\\s+.*?(?=(?:,|$|and))
(?m)
表示在进行解析时启用MULTILINE标志。
在多行模式中,表达式^和$分别在行终止符之后或之前或输入序列的末尾匹配。默认情况下,这些表达式仅匹配整个输入序列的开头和结尾。