C#Regex多重匹配

时间:2018-04-19 16:29:58

标签: c# regex

我希望(在C#中)检查语法并从字符串中提取一些数据。 检查字符串是否包含:“someWord IS someWord( OR someWord){1-infinite}” 并提取每个单词,并为第一个单词命名组“switch”

这是我的字符串:

string text = "[bird] IS blue OR yellow OR green";

所以我使用这个正则表达式

string switchPattern = @"\s*(?<switch>.+?)\s+IS\s+(.+?)(?:\s+OR\s+(.+?))+$";

提取
Match switchCaseMatch = Regex.Match(text, switchCaseOperatorPattern);

这给了我一个包含4个元素的小组

[0]: [bird] IS blue OR yellow OR green
[1]: green
[2]: blue
[3]: [bird]  named switch

但我想要

[0]: [bird] IS blue OR yellow OR green
[1]: green
[2]: yellow
[3]: blue
[4]: [bird]  named switch

我希望最后一个“(.+?)”会为所有匹配的情况创建一个组,但它最后只会创建一个组。我尝试使用Regex.Matches并获得相同的结果。

我知道我可以使用两个正则表达式(Regex.Match然后使用Regex.Matches作为“someWord( OR someWord){1-infinite}”),但我想知道是否可以只使用一个正则表达式。

由于

2 个答案:

答案 0 :(得分:3)

实际上,您可以使用Regex.Match,{I} Captures,正如我在评论中所说的那样。这是一个代码示例:

        string text = "[bird] IS blue OR yellow OR green";
        string switchPattern = @"\s*(?<switch>.+?)\s+IS\s+(.+?)(?:\s+OR\s+(.+?))+$";

        Match switchCaseMatch = Regex.Match(text, switchPattern);
        foreach (Group group in switchCaseMatch.Groups)
        {
            if (group.Captures.Count == 1)
                Console.WriteLine(group.Value);
            else foreach (Capture cap in group.Captures)
                    Console.WriteLine(cap.Value);
        }

这导致:

[bird] IS blue OR yellow OR green
blue
yellow
green
[bird]

有关详细信息,请参阅Microsoft MSDN page for Captures

答案 1 :(得分:0)

我认为使用群组会很困难,因为您需要预测您将拥有多少群组。我建议使用Matches方法和MatchCollection代替。您可以访问其中的命名组,也可以捕获您所追踪的所有目标字符串。

e.g。

string text = "[bird] IS blue OR yellow OR green";
string switchPattern = @"(?<=(?<switch>\S+)\s+IS.*?)(\w+(?=\s+OR)|(?<=OR\s+)\w+)";
MatchCollection switchCaseMatch = Regex.Matches(text, switchPattern);

foreach (Match m in switchCaseMatch)
{
    Console.WriteLine(m.Groups["switch"].Value);
    Console.WriteLine(m.Value);
}

您构建模式以使用无限制的lookbehind来搜索switch(组)文本。这将强制每次出现的颜色都遵循该文本。该外观中的点星将消耗在先前迭代中捕获的所有颜色文本。然后,你使用前瞻来找到第一种颜色(通过确保“OR”跟随颜色)或者使用lookbehind来找到所有后续颜色(通过确保“OR”在颜色之前。然后它只是评估Value中每个Match对象的MatchCollection属性。将在每个Match中捕获已命名的组,以便您也可以访问该组。