查找具有额外资格标准的所有比赛
给出句子如;
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)
返回最后一个匹配动物的整个短语,例如“Boy has a dog and a cat”,而第一个也是唯一一个组是“cat”。
如何获得与“男孩”相关的所有动物的列表(即以“男孩”开头的句子中的动物)?
您可以使用积极的观察:
(?<=^Boy.*?)(?:dog|cat|gerbil)
或者,带有单词边界的变体以匹配动物作为整个单词:
(?<=^Boy\b.*?)\b(?:dog|cat|gerbil)\b
请参阅正则表达式演示
(?<=^Boy.*?)
正向后视将需要在字符串开头的Boy
用于匹配消费模式。
如果您的输入包含LF(换行符)字符,请传递RegexOptions.Singleline
选项.
也匹配换行符。
C#用法:
var results = Regex.Matches(s, @"(?<=^Boy\b.*?)\b(?:dog|cat|gerbil)\b") .Cast() .Select(m => m.Value) .ToList();
C#演示 :
var strs = new List() { "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() .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
开头的字符串,然后在每次成功匹配后:
(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b
请参阅此正则表达式演示 (或此处的regex101链接 )
您只需要抓取第1组内容:
var results = Regex.Matches(s, @"(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b") .Cast() .Select(m => m.Groups[1].Value) .ToList();
看到这个C#演示 。
这里,
-
(?:\G(?!\A)|^Boy\b)
- 前级匹配的结束(\G(?!\A)
)或字符串的开头后跟整个单词Boy
-
.*?
- 除了换行符之外的任何0+字符(如果没有将RegexOptions.Singleline
传递给Regex
构造函数)尽可能少 -
\b(dog|cat|gerbil)\b
- 整个单词dog
,cat
或gerbil
基本上,这些正则表达式是相似的,尽管\G
基于\G
的正则表达式可能会更快一些。