正则表达式:优先考虑可选模式

时间:2017-10-29 09:47:16

标签: c# regex

我们说我有一个这样的字符串:

555 3553 666 555

像这样的正则表达式

var pat = new Regex("3?553?");

当上面的字符串匹配pat.Match(mystring)时,返回的结果将是" 55"。 我需要将结果返回到" 3553"如果可能的话,如果没有,那么我才希望结果是" 55"。如:3?是可选的,不必在那里,但如果是,它将始终首先匹配。

因此555 3553 666 555将返回3553

222 5555 777将返回55

这可以在不使用两个单独的正则表达式定义的情况下实现吗?

谢谢。

3 个答案:

答案 0 :(得分:0)

你的正则表达式匹配55只是因为那是它能找到的第一个匹配。与优先事项无关。

我认为你想要的是获得最长的比赛。您应该使用Matches获取所有匹配项,并通过选中Length来获取最长的匹配项。

var matches = Regex.Matches("555 3553 666 555", "3?553?");
var longestMatch = matches.Cast<Match>().OrderByDescending(x => x.Value.Length).First().Value

答案 1 :(得分:0)

正则表达式引擎总是从左到右遍历字符串(假设从左到右的脚本)。在您的情况下,前两个字符与正则表达式匹配,因此它返回。

因此,您不必在第一场比赛后停止,而是需要进行所有比赛并选择最长的比赛。但是,有一点需要注意:正则表达式匹配不能重叠(每个字符只能匹配一次)。因此,在像

这样的字符串中
55553553

您的正则表达式将返回55553553

解决方案是使用lookahead assertion,并结合捕获组:

var pat = new Regex("(?=(3?553?))", "g");

并获得所有匹配

var match = pat.exec(subject);
while (match != null) {
    // matched text: match[1], add that to an array
    }
    match = pat.exec(subject);
}

然后选择最长的匹配。

答案 2 :(得分:0)

如果是的话,我认为您希望使用优先级而不是匹配!我认为以下代码可以帮助您:

var matches = Regex.Matches(txt, @"(?<G1>3553)|(?<G2>55)").OfType<Match>();
var res = matches
        .GroupBy(x => x.Success)
        .Select(x => 
            new {
                    Success = x.Key,
                    G = !string.IsNullOrEmpty(x.Max(w => w.Groups["G1"].Value))
                        ? x.Max(w => w.Groups["G1"].Value)
                        : x.Max(w => w.Groups["G2"].Value)
                })
        .SingleOrDefault();

C# Demo