Skip to main content
 首页 » 编程设计

c#之通过方法处理每个单独的正则表达式匹配的好模式是什么

2024年02月02日25zdz8207

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

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)。