【问题标题】:Determine Regular Expression replacement string without Replacing确定正则表达式替换字符串而不替换
【发布时间】:2018-10-30 03:02:57
【问题描述】:

如果我有一些文字:

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 一起使用。

【问题讨论】:

  • 看来你想要RegEx.Matches(myText,searchPatten).Cast<Match>().Select(x => $"{x.Groups[1].Value} xx{x.Groups[2].Value}")
  • 您是正确的,您的答案将适用于特定的 replacePattern,但我需要任何 searchPattern 和 replacePattern 的通用解决方案。抱歉,应该更清楚地说明一般解决方案的要求。

标签: c# regex


【解决方案1】:

您能做的最好的事情是使用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 也不公开它用于替换模式的解释器。

【讨论】:

    【解决方案2】:

    我最终为 Match 编写了一个名为 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 xxThis is the first line\r\n”。它不支持命名组,也不检查转义的 $,但它适用于我当前的所有用途。

    【讨论】:

      猜你喜欢
      • 2018-07-13
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 2012-04-26
      • 2012-10-08
      相关资源
      最近更新 更多