【问题标题】:Regex matching multiple field value in a single line正则表达式匹配单行中的多个字段值
【发布时间】:2021-07-28 08:23:35
【问题描述】:

我希望在一行中匹配由冒号分隔的多个字段值,但每个字段和值文本都包含空格 例如

field1   :    value1a  value1b

answer
match1: Group1=field1, Group2=value1a value1b

field1   :    value1a  value1b   field2   : value2a value2b

answer
match1: Group1=field1, Group2=value1a value1b
match2: Group1=field2, Group2=value2a value2b

我现在能做的最好的就是 (\w+)\s*:\s*(\w+)

Regex regex = new Regex(@"(\w+)\s*:\s*(\w+)");
Match m = regex.Match("field1   :    value1a  value1b   field2   : value2a value2b");
while (m.Success)
{
   string f = m.Groups[1].Value.Trim();
   string v = m.Group2[2].Value.Trim();
}

我想向前看可能会有所帮助,但我不知道如何做到这一点 谢谢

【问题讨论】:

  • 如果你想要Group1Group2等标签,你必须从你的编程语言中生成它们。单独的正则表达式无法做到这一点。
  • 这只是一个插图,我编辑了问题以显示示例代码。谢谢

标签: c# regex


【解决方案1】:

你可以试试

(\w+)\s*:\s*((?:(?!\s*\w+\s*:).)*)
  • (\w+) 第 1 组,任意连续单词
  • \s*:\s* 冒号,周围有空格
  • (...)第二组
  • (?:...)* 非捕获组,随时重复
  • (?!\s*\w+\s*:). 否定前瞻,前面有一个字符,后面的字符不能形成一个由任何空格和冒号包围的单词。因此,第 2 组从不使用冒号前的任何单词

test cases

【讨论】:

  • 谢谢,它有效。但我不太明白在负面展望之后最后一个点是什么。
  • 点只匹配任何字符,但在匹配之前,否定前瞻检查它是否是冒号前单词的一部分。如果是,则整场比赛在该点结束。每次点与字符匹配时,此前瞻都会检查。
  • 它适用于不确定数量的值。如果值的数量固定为 2。一个简单的 (\w+)\s*:\s*(\w+\s+\w+) 就可以了
【解决方案2】:

您可以使用基于惰性点的正则表达式:

var matches = Regex.Matches(text, @"(\w+)\s*:\s*(.*?)(?=\s*\w+\s*:|$)");

请参阅 C# demo online.NET regex demo(请注意 regex101.com 不支持 .NET 正则表达式风格)。

如您所见,无需使用tempered greedy token。正则表达式的意思是:

  • (\w+) - 第 1 组:任何一个或多个字母/数字/下划线
  • \s*:\s* - 用零个或多个空格字符括起来的冒号
  • (.*?) - 第 2 组:除换行符之外的任何零个或多个字符,尽可能少
  • (?=\s*\w+\s*:|$) - 直到第一次出现一个或多个用零个或多个空格或字符串结尾包围的单词字符。

完整的 C# 演示:

using System;
using System.Text.RegularExpressions;

public class Test
{
    public static void Main()
    {
        var text = "field1   :    value1a  value1b   field2   : value2a value2b";
        var matches = Regex.Matches(text, @"(\w+)\s*:\s*(.*?)(?=\s*\w+\s*:|$)");
        foreach (Match m in matches)
        {
            Console.WriteLine("-- MATCH FOUND --\nKey: {0}, Value: {1}", 
                m.Groups[1].Value, m.Groups[2].Value);
        }
    }
}

输出:

-- MATCH FOUND --
Key: field1, Value: value1a  value1b
-- MATCH FOUND --
Key: field2, Value: value2a value2b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多