如何在用于替换的正则表达式匹配中获取捕获组

时间:2018-02-09 17:55:01

标签: c# regex replace

我有以下程序演示替换正则表达式搜索中找到的匹配项:

using System;

public class Test {
    public static void Main() {
        var regexSearch = @"\{(\w+)\}";
        var format = "{Level}:{Name}:{Message}";
        var regex = new System.Text.RegularExpressions.Regex(regexSearch);
        var result = regex.Replace(format, Test.Replace);
        Console.WriteLine($"result = {result}");
    }

    public static string Replace(System.Text.RegularExpressions.Match match) {
        Console.WriteLine($"match = {match}");
        return "<replacement>";
    }
}

这会将以下内容打印到标准输出:

match = {Level}
match = {Name}
match = {Message}
result = <replacement>:<replacement>:<replacement>

如果只更改Replace方法,我如何才能获得打印以下内容的代码?

match = Level
match = Name
match = Message
result = Level:Name:Message

我知道Match.GroupsMatch.Captures,但要继续查找包含大括号的字符串。

以下示例更能说明我的真正目标:

using System;

public class Test {
    public static void Main() {
        var regexSearch = @"\{(\w+)\}";
        var format = "{Level}:{Name}:{Message}";
        var regex = new System.Text.RegularExpressions.Regex(regexSearch);
        var record = new Information(Importance.Normal, "John Doe", "Hello, world!");
        var result = regex.Replace(format, x => Test.Replace(x, record));
        Console.WriteLine($"result = {result}");
    }

    public static string Replace(System.Text.RegularExpressions.Match match, Information record) {
        Console.WriteLine($"match = {match}");
        var name = "Level";
        var property = record.GetType().GetProperty(name);
        if (property == null) {
            throw new InvalidOperationException($"{name} is not available");
        }
        var value = property.GetValue(record);
        if (value is DateTime) {
            return ((DateTime)value).ToString("yyyy-MM-ddTHH:mm:ss");
        }
        return value.ToString();
    }
}

public class Information {
    public Importance Level { get; }
    public string Name { get; }
    public string Message { get; }
    public DateTime Created { get; }

    public Information(Importance level, string name, string message) {
        this.Level = level;
        this.Name = name;
        this.Message = message;
        this.Created = DateTime.Now;
    }
}

public enum Importance {
    Low,
    Normal,
    Hight
}

该程序几乎完全符合预期,但将其写入标准输出:

match = {Level}
match = {Name}
match = {Message}
result = Normal:Normal:Normal

该计划的第15行显示var name = "Level";,并且需要在匹配的捕获组中获取该名称。输出应该这样说:

match = {Level}
match = {Name}
match = {Message}
result = Normal:John Doe:Hello, world!

有谁知道如何获取正则表达式捕获组的内容,以便第15行可以替换为结果?

2 个答案:

答案 0 :(得分:0)

您的问题是您的Replace方法中的以下代码,它只是寻找名称 - &gt; &#34;级&#34;

如果你进入调试模式,在你的替换方法中放一个断点,在它上面放一个f11 ...你会看到每个循环&#39;对于该方法,该属性将始终为&#34; Level&#34;

你可以做几件事来解决这个问题......比如包括一个每次调用方法时增加1的计数器......后跟一个switch语句来确定什么名称应该等于...等等的东西。

答案 1 :(得分:0)

您遇到的问题是您对Groups的期望不正确。它不仅包含每个捕获组,还包含整个匹配。它的长度应该比预期长一个,第一组应该是第一个。

在您的第一个示例中,更改第14行,使其显示为:

return match.Groups[1].Value;

在第二个示例中,更改第15行,使其显示为:

var name = match.Groups[1].Value;