确定正则表达式替换字符串而不替换

时间:2018-05-20 06:14:31

标签: c# regex

如果我有一些文字:

string myText = "01001001 -This is the first line\r\n" + 
                "01001002 -This is the 2nd line\r\n" + 
                "01002003 This is the third line\r\n";

我有一个正则表达式替换命令:

string searchPattern = "([0-9]{8}) -([^-])?";
string replacePatten = "$1 xx$2";
RegEx.Replace(myText,searchPatten,replacePattern);

这很好用,我得到了结果:

myText = "01001001 xxThis is the first line\r\n" + 
         "01001002 xxThis is the 2nd line\r\n" + 
         "01002003 This is the third line\r\n";

然而,我真正想要的是类似于RegEx.Matches,除了我还想知道替换字符串是什么。如下所示:

Matches matches = RegEx.Matches(myText,searchPattern,replacePattern);

这将导致匹配集合有两个结果。我会知道每个匹配的索引和长度以及它将替换为:

matches[0].ToString() = {Index=0,Length=10,ReplacedWith="01001001 xxThis is the first line\r\n"}
matches[1].ToString() = {Index=36,Length=10,ReplacedWith="01001002 xxThis is the second line\r\n"}

所以我希望能够在不实际替换它的情况下计算替换字符串。我查看了MatchEvaluator Delegates,但我不知道如何将它与searchPattern绑定的replacePattern一起使用。

2 个答案:

答案 0 :(得分:0)

您可以做的最好的事情是使用Regex.Matches(),然后在每个Match上执行Regex.Replace()

var regex = new Regex(searchPattern);

var matches = regex.Matches(myText)
    .Cast<Match>()
    .Select(x => new
    {
        Match = x,
        ReplacedWith = regex.Replace(x.Value, replacePatten)
    })
    .ToArray();

Regex.Replace在内部使用Matches但不公开其内容,Regex也不会公开它用于替换模式的解释器。

答案 1 :(得分:0)

我最终写了一个名为Replacement的匹配扩展名:

public static string Replacement(this Match match, string replacePattern)
{
        if (replacePattern.Contains("$"))
        {
            //there is substitutes
            string result = replacePattern;
            for (int i = 1; i < match.Groups.Count; i++)
            {
                //Group[0] is the full match, so start with each captured group
                result = result.Replace("$" + i.ToString(), match.Groups[i].Value);
            }
            return result;
        }
        else
        {
            //no substitutes
            return replacePattern;
        }
}

在我的原始示例中,我可以致电:

string newString = match.Replacement("$1 xx$2");
然后

newString将包含“01001001 xx这是第一行\ r \ n”。它不支持命名组,也不会对转义$进行任何检查,但它适用于我目前的所有用途。