查找具有额外资格标准的所有比赛

时间:2017-11-06 20:14:05

标签: 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.*(dog|cat|gerbil)

Returns整个短语直到最后一个匹配的动物,例如“男孩有一只狗和一只猫”,而第一个也是唯一一个组是“猫”。

如何获取与“男孩”相关的所有动物的列表(即以“男孩”开头的句子中的动物)?

1 个答案:

答案 0 :(得分:3)

你可以使用积极的外观:

(?<=^Boy.*?)(?:dog|cat|gerbil)

或者,带有单词边界的变体以匹配动物作为整个单词:

(?<=^Boy\b.*?)\b(?:dog|cat|gerbil)\b

请参阅regex demo

(?<=^Boy.*?)正向后视将需要字符串开头的Boy来匹配消费模式。

如果您的输入包含LF(换行符)字符,请传递RegexOptions.Singleline的{​​{1}}选项以匹配换行符。

C#用法:

.

C# demo

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)\bdogcat

基本上,这些正则表达式类似,但基于gerbil的正则表达式可能会更快一些。