1

我试图找出一个模式,我在长字符串上运行正则表达式匹配,每次找到匹配时,它都会对其运行替换。问题是,替换将根据匹配的值而有所不同。这个新值将由一种方法确定。例如:

var matches = Regex.Match(myString, myPattern);
while(matches.Success){
   Regex.Replace(myString, matches.Value, GetNewValue(matches.Groups[1]));
   matches = matches.NextMatch();
}

问题(我认为)是,如果我运行 Regex.Replace,所有匹配索引都会变得混乱,因此结果最终会出错。有什么建议么?

4

3 回答 3

4

如果你用一个固定的字符串替换每个模式Regex.replace,为你做这件事。您不需要迭代匹配项:

Regex.Replace(myString, myPattern, "replacement");

否则,如果替换依赖于匹配的值,则使用MatchEvaluator委托作为 的第三个参数Regex.Replace。它接收一个实例Match并返回string。返回值是替换字符串。如果您不想替换某些匹配项,只需返回match.Value

string myString = "aa bb aa bb";
string myPattern = @"\w+";
string result = Regex.Replace(myString, myPattern, 
                      match => match.Value == "aa" ? "0" : "1" );
Console.WriteLine(result);
// 0 1 0 1

如果您确实需要迭代匹配并手动替换它们,则需要从最后一个匹配开始替换到第一个匹配,这样字符串的索引就不会为即将到来的匹配而破坏。这是一个例子:

var matches = Regex.Matches(myString, myPattern);
var matchesFromEndToStart = matches.Cast<Match>().OrderByDescending(m => m.Index);
var sb = new StringBuilder(myString);
foreach (var match in matchesFromEndToStart)
{
    if (IsGood(match))
    {
        sb.Remove(match.Index, match.Length)
          .Insert(match.Index, GetReplacementFor(match));
    }
}

Console.WriteLine(sb.ToString());

请注意,您的匹配项不包含嵌套实例。如果是这样,您要么需要删除另一个匹配项中的匹配项,要么在每次替换后重新运行正则表达式模式以生成新匹配项。我仍然推荐第二种方法,它使用代表。

于 2013-02-05T03:53:25.133 回答
1

如果我正确理解您的问题,您希望基于常量正则表达式执行替换,但您使用的替换文本将根据正则表达式匹配的实际文本而改变。

Match 类的 Captures 属性(不是 Match 方法)返回输入字符串中与您的正则表达式匹配的所有匹配项的集合。它包含字符串中的位置、匹配值和匹配长度等信息。如果您使用 foreach 循环遍历此集合,您应该能够单独处理每个匹配项并执行一些字符串操作,您可以在其中动态修改替换值。

于 2013-02-05T04:01:53.010 回答
0

我会使用类似的东西

Regex regEx = new Regex("some.*?pattern");
string input = "someBLAHpattern!";
foreach (Match match in regEx.Matches(input))
{
    DoStuffWith(match.Value);
}
于 2013-02-05T04:08:05.110 回答