4

我正在使用带有MatchEvaluator委托的正则表达式来处理格式字符串,例如时间:%t,字节:%b”将用时间戳替换“%t” ,用字节数替换“%b”。不用说,还有很多其他选择!

为此,我使用:

    Regex regex = new Regex("%((?<BytesCompleted>b)|(?<BytesRemaining>B)|(?<TimeStamp>t))");
    string s = "%bhello%t(HH:MM:SS)%P";
    string r = regex.Replace(s, new MatchEvaluator(ReplaceMatch));

string ReplaceMatch(Match m)
{
    ... Handle the match replacement.
}

如果我可以在委托中使用正则表达式组名称(甚至是数字,我没那么挑剔)而不是与原始匹配进行比较以找出这是哪个匹配,那将是一件好事:

string ReplaceMatch(Match m)
{
    ...
    case "%t":
    ...
    case "%b";
    ...
}

很丑;我想用

string ReplaceMatch(Match m)
{
    ...
    case "BytesCompleted":
    ...
    case "TimeStamp":
    ...
}

通过调试器或谷歌,我看不到任何明显的东西。有任何想法吗?

4

3 回答 3

0

能够在 switch 中使用组名会很好;不幸的是,该Group对象没有Name属性(它的基类也没有Capture),所以您能做的最好的事情如下:

string ReplaceMatch(Match m)
{
    if (m.Groups["BytesCompleted"].Success) // ...
    else if (m.Groups["BytesRemaining"].Success) // ...
    // ...
}
于 2013-05-29T00:51:15.337 回答
0

您可以使用Regex.GroupNameFromNumber实例方法,不幸的是,这意味着匹配评估器方法需要对Regex对象的引用:

string ReplaceMatch(Match m)
{
    for (int i = 0; i < m.Groups.Count; i++)
    {
        string groupName = _regex.GroupNameFromNumber(i);
        switch (groupName)
        {
            case "BytesCompleted":
                // do something
                break;
            case "BytesRemaining":
                // do somehting else
                break;
            ...
        }
    }
    ...
}

这里我假设Regex对象可以通过_regex变量访问。

于 2013-05-29T00:57:49.053 回答
0

我们需要结合新浪和詹姆斯的答案。我们需要枚举组以获取索引并检查组是否成功。然后我们使用索引来获取组名。我已经扩展了一个不言自明的测试,它使用字典来替换匹配的子字符串。如果在框架中对组名提供更多支持,这会容易得多。

另请参阅可能对您有用的另一个答案:https ://stackoverflow.com/a/1381163/481812

[Test]
public void ExploreRxReplace()
{
    var txt = " ABC XYZ DEF ";
    var exp = " *** XYZ xxx ";
    var rx = new Regex(@"\s*(?<abc>ABC)\s*|\s*(?<def>DEF)\s*");
    var data = new Dictionary<string, string>() { { "abc", "***" }, { "def", "xxx" } };

    var txt2 = rx.Replace(txt, (m) =>
    {
        var sb = new StringBuilder();
        var pos = m.Index;

        for (var idx = 1; idx < m.Groups.Count; idx++)
        {
            var group = m.Groups[idx];

            if (!group.Success)
            {
                // ignore non-matching group
                continue;
            }

            var name = rx.GroupNameFromNumber(idx);

            // append what's before
            sb.Append(txt.Substring(pos, group.Index - pos));

            string value = null;
            if (group.Success && data.TryGetValue(name, out value))
            {
                // append dictionary value
                sb.Append(value);
            }
            else
            {
                // append group value
                sb.Append(group.Value);
            }

            pos = group.Index + group.Length;
        }

        // append what's after
        sb.Append(txt.Substring(pos, m.Index + m.Length - pos));

        return sb.ToString();
    });

    Assert.AreEqual(exp, txt2);
}
于 2016-06-20T13:21:57.220 回答