我试图找出一种模式,在该模式中我对长字符串运行正则表达式匹配,并且每次找到匹配项时,它都会对其运行替换。问题是,替换将根据匹配值而有所不同。这个新值将由一种方法确定。例如:
var matches = Regex.Match(myString, myPattern);
while(matches.Success){
Regex.Replace(myString, matches.Value, GetNewValue(matches.Groups[1]));
matches = matches.NextMatch();
}
问题(我认为)是如果我运行 Regex.Replace,所有的匹配索引都会被弄乱,所以结果最终会出错。有什么建议吗?
请您参考如下方法:
如果您用固定字符串替换每个模式,Regex.replace 会为您完成。您不需要迭代匹配项:
Regex.Replace(myString, myPattern, "replacement");
否则,如果替换取决于匹配值,请使用 MatchEvaluator 委托(delegate)作为 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());
请注意,您的匹配项不包含嵌套实例。如果是这样,您要么需要删除另一个匹配项中的匹配项,要么重新运行正则表达式模式以在每次替换后生成新的匹配项。我仍然推荐第二种方法,即使用委托(delegate)。
