【问题标题】:How do I replace only specific match in a match collection?如何仅替换匹配集合中的特定匹配?
【发布时间】:2015-07-27 15:55:11
【问题描述】:

我正在编写一个求解方程的求解方法。该方法将是递归的;搜索所有外圆括号,找到后调用解决圆括号内的值,并在没有找到圆括号时返回值。

流程应该是这样的

20 * (6+3) / ((4+6)*9)
20 * 9 / ((4+6)*9)
20 * 9 / (10*9)
20 * 9 / 90
2

如您所见,每个匹配项可能具有不同的替换值。我需要将括号替换为它的评估结果。有没有办法做到这一点。这是我目前所拥有的。

public int solve(string etq)
{
    Regex rgx = new Regex(@"\(([^()]|(?R))*\)");
    MatchCollection matches;

    matches = rgx.Matches(etq);
        
    foreach(Match m in matches)
    {
        //replace m in etq with unique value here
    }

    //calculations here
    return calculation
}

Regex.replace(...) 替换所有出现的指定模式。我希望能够匹配多个场景并用不同的输出替换每个场景

【问题讨论】:

  • 我不认为你的代码在 C# 中工作。您是否从 PHP/Perl 复制代码并希望它可以在 C# 中工作? C# 不支持调用例程语法(?R)。它只支持平衡组。
  • 你为什么不用proper solution 来代替呢?正则表达式的方式很痛苦。

标签: c# regex string


【解决方案1】:

简单的解决方案:

string input = "20 * (6+3) / ((4+6)*9)";
Console.WriteLine(input);
DataTable dt = new DataTable();
Regex rx = new Regex(@"\([^()]*\)");
string expression = input;
while (rx.IsMatch(expression))
{
    expression = rx.Replace(expression, m => dt.Compute(m.Value, null).ToString(), 1);
    Console.WriteLine(expression);
}
Console.WriteLine(dt.Compute(expression, null));

https://dotnetfiddle.net/U6Hh1e

【讨论】:

  • 不错,我不知道DataTable.Compute。现在我在这堂课中找到DataTable.MakeCoffee 不会感到惊讶。 :-)
  • 由于这适用于我给出的表达式,我将添加其他函数,例如平方根、倒数、模数和其他我不确定这是否适用的函数。
  • @Benjamin 好吧,主要问题是关于找到(...) 并将其替换为计算结果。使用 DataTable 计算结果只是一个示例。如果需要更强大的计算引擎,可以使用 NCalc - ncalc.codeplex.com
【解决方案2】:

这将是一个更简单的解决方案,使用匹配属性来替换使用子字符串:

public static string Replace(this Match match, string source, string replacement) { return source.Substring(0, match.Index) + replacement + source.Substring(match.Index + match.Length); }

【讨论】:

  • 值得补充的是,如果你想替换选择数量的匹配,你可以使用这个功能,但是你需要添加一个索引修饰符,你将根据字符串长度的变化来改变.然后使用将索引修饰符添加到匹配索引(从 0 开始修饰符)。
猜你喜欢
  • 2012-03-10
  • 2022-06-27
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多