给出句子,如;
Boy has a dog and a cat.
Boy microwaves a gerbil.
Sally owns a cat.
对于每个句子,我想要一个动物列表(定义为'狗'猫'或'沙鼠'),其中“男孩”是第一个单词。对于上面的列表,将是;
['dog', 'cat']
['gerbil']
3rd sentence would not match.
正则表达式;
dog|cat|gerbil
将返回所有匹配,但不是特定于男孩(第三句会返回一个不受欢迎的'猫')。
^Boy.*(dog|cat|gerbil)
Returns整个短语直到最后一个匹配的动物,例如“男孩有一只狗和一只猫”,而第一个也是唯一一个组是“猫”。
如何获取与“男孩”相关的所有动物的列表(即以“男孩”开头的句子中的动物)?
答案 0 :(得分:3)
你可以使用积极的外观:
(?<=^Boy.*?)(?:dog|cat|gerbil)
或者,带有单词边界的变体以匹配动物作为整个单词:
(?<=^Boy\b.*?)\b(?:dog|cat|gerbil)\b
请参阅regex demo
(?<=^Boy.*?)
正向后视将需要字符串开头的Boy
来匹配消费模式。
如果您的输入包含LF(换行符)字符,请传递RegexOptions.Singleline
的{{1}}选项以匹配换行符。
C#用法:
.
var results = Regex.Matches(s, @"(?<=^Boy\b.*?)\b(?:dog|cat|gerbil)\b")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
输出:
var strs = new List<string>() { "Boy has a dog and a cat.",
"Boy something a gerbil.",
"Sally owns a cat." };
foreach (var s in strs)
{
var results = Regex.Matches(s, @"(?<=^Boy\b.*?)\b(?:dog|cat|gerbil)\b")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
if (results.Count > 0) {
Console.WriteLine("{0}:\n[{1}]\n------", s, string.Join(", ", results));
}
else
{
Console.WriteLine("{0}:\nNO MATCH!\n------", s);
}
}
有一个替代:匹配任何以Boy has a dog and a cat.:
[dog, cat]
------
Boy something a gerbil.:
[gerbil]
------
Sally owns a cat.:
NO MATCH!
------
开头的字符串,然后在每次成功匹配后匹配:
Boy
请参阅this regex demo(或regex101 link here)
您只需要抓取第1组内容:
(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b
请参阅this C# demo。
下面,
var results = Regex.Matches(s, @"(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToList();
- 前置匹配((?:\G(?!\A)|^Boy\b)
)的结束或字符串的开头后跟整个单词\G(?!\A)
Boy
- 除了换行符之外的任何0 +字符(如果没有.*?
传递给RegexOptions.Singleline
构造函数)尽可能少Regex
- 整个字\b(dog|cat|gerbil)\b
,dog
或cat
基本上,这些正则表达式类似,但基于gerbil
的正则表达式可能会更快一些。