C# 查找具有额外资格标准的所有匹配项
给出如下句子:C# 查找具有额外资格标准的所有匹配项,c#,regex,C#,Regex,给出如下句子: 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(第三句将返回不受欢迎的“cat”)
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(第三句将返回不受欢迎的“cat”)
整个短语直到最后一个匹配的动物,例如“男孩有一只狗和一只猫”,而第一组也是唯一一组是“猫”
如何获得与“Boy”(即以“Boy”开头的句子中的动物)相关的所有动物的列表?您可以使用积极的回顾:
(?<=^Boy.*?)(?:dog|cat|gerbil)
:
还有另一种选择:匹配任何以Boy
开头的字符串,然后仅在每次成功匹配后匹配:
(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b
见(或a)
您只需抓取第1组内容:
var results = Regex.Matches(s, @"(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToList();
var results=Regex.Matches(s,@“(?:\G(?!\A)^ Boy\b.*?\b(狗|猫|沙鼠)\b”)
.Cast()
.Select(m=>m.Groups[1]。值)
.ToList();
看
这里,
-前一个匹配的结尾((?:\G(?!\A)^Boy\b)
)或字符串的开头,后跟整个单词\G(?!\A)
Boy
-除换行符以外的任何0+字符(如果没有*?
传递给RegexOptions。将单行
构造函数)尽可能少Regex
-一个完整的单词\b(狗|猫|沙鼠)\b
,狗
或猫
沙鼠
基本上,这些正则表达式是相似的,尽管基于
\G
的正则表达式可能会快一点。这是否需要解释像男孩没有沙鼠但有猫这样的事情?那可能会很棘手,不。如果是从男孩开始的话,我希望所有的动物都在那句话里。无论是比赛还是团体,我都不在乎,我只需要动物一个人,在所有以“男孩”开头的短语中。编辑问题以消除歧义。只需使用(?可能应该确保^Boy\b
,尽管第一个词可能是抵制@ctwheels是的,那应该是第二个建议。@n00b还有另一个选择-(?:\G(?)\A)|^Boy\b.*?\b(狗|猫|沙鼠)
和抓m.Groups[1].Value
。是否可以通过分组而不是匹配来完成相同的最终目标(即第一句话将第一组返回为“dog”,第二组返回为“cat”)?@n00b否,因为在模式+1中捕获组的组数与(…)
的组数相同(整个匹配在第0组中)。您可以通过捕获
访问它们,但我认为这是不合理的。您还有什么其他要求?
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!
------
(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b
var results = Regex.Matches(s, @"(?:\G(?!\A)|^Boy\b).*?\b(dog|cat|gerbil)\b")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToList();