我如何使用RegEx选择最长的比赛

本文关键字:选择 何使用 RegEx | 更新日期: 2023-09-27 18:08:58

我试着寻找这个问题的答案,但只是找不到任何东西,我希望有一个简单的解决方案。我在c#中使用了以下代码,

String pattern = ("(hello|hello world)");
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
var matches = regex.Matches("hello world");

问题是,是否有一种方法可以让匹配方法首先返回最长的模式?在这个例子中,我想要得到"hello world"作为我的匹配,而不是"hello"。这只是一个例子,但是我的模式列表包含了相当数量的单词。

我如何使用RegEx选择最长的比赛

如果事先已经知道单词的长度,那么就把最长的放在前面。例如:

String pattern = ("(hello world|hello)");

最长的将首先匹配。如果你事先不知道长度,这是不可能的。

另一种方法是将所有匹配项存储在数组/散列/列表中,并使用语言的内置函数手动选择最长的匹配项。

正则表达式(将尝试)从左到右匹配模式。如果您想确保首先获得最长的匹配,则需要更改模式的顺序。首先尝试最左边的模式。如果在该模式下找到匹配,正则表达式引擎将尝试将模式的其余部分与字符串的其余部分进行匹配;只有在没有找到匹配的情况下才会尝试下一个模式。

String pattern = ("(hello world|hello wor|hello)");

进行两个不同的正则表达式匹配。第一个将匹配较长的选项,如果这不起作用,第二个将匹配较短的选项。

string input = "hello world";
string patternFull = "hello world";
Regex regexFull = new Regex(patternFull, RegexOptions.IgnoreCase);
var matches = regexFull.Matches(input);
if (matches.Count == 0)
{
    string patternShort = "hello";
    Regex regexShort = new Regex(patternShort, RegexOptions.IgnoreCase);
    matches = regexShort.Matches(input);
}

最后,matches将是"满"或"短"输出,但首先检查"满",如果为真则会短路。

如果你打算多次调用它,你可以将逻辑包装在一个函数中。这是我想出来的(但还有很多其他方法可以做到这一点)。

public bool HasRegexMatchInOrder(string input, params string[] patterns)
{
    foreach (var pattern in patterns)
    {
        Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
        if (regex.IsMatch(input))
        {
            return true;
        }
    }
    return false;
}
string input = "hello world";
bool hasAMatch = HasRegexMatchInOrder(input, "hello world", "hello", ...);