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

C# 通过方法处理每个正则表达式匹配的好模式是什么,c#,.net,regex,C#,.net,Regex,我试图找出一个模式,在这个模式中,我在一个长字符串上运行一个正则表达式匹配,每次它找到一个匹配,它都在它上面运行一个替换。问题是,替换将根据匹配的值而变化。该新值将由一种方法确定。例如: var matches = Regex.Match(myString, myPattern); while(matches.Success){ Regex.Replace(myString, matches.Value, GetNewValue(matches.Groups[1])); matche

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

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
委托作为
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());
var matches=Regex.matches(myString,myPattern);
var matchesFromEndToStart=matches.Cast().OrderByDescending(m=>m.Index);
var sb=新StringBuilder(myString);
foreach(matchesFromEndToStart中的变量匹配)
{
如果(很好(匹配))
{
删除(匹配索引、匹配长度)
.Insert(match.Index,GetReplacementFor(match));
}
}
Console.WriteLine(sb.ToString());

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

如果您使用固定字符串替换每个模式,
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());
var matches=Regex.matches(myString,myPattern);
var matchesFromEndToStart=matches.Cast().OrderByDescending(m=>m.Index);
var sb=新StringBuilder(myString);
foreach(matchesFromEndToStart中的变量匹配)
{
如果(很好(匹配))
{
删除(匹配索引、匹配长度)
.Insert(match.Index,GetReplacementFor(match));
}
}
Console.WriteLine(sb.ToString());

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

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


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

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


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

我将使用类似于

Regex regEx = new Regex("some.*?pattern");
string input = "someBLAHpattern!";
foreach (Match match in regEx.Matches(input))
{
    DoStuffWith(match.Value);
}

我会用像这样的东西

Regex regEx = new Regex("some.*?pattern");
string input = "someBLAHpattern!";
foreach (Match match in regEx.Matches(input))
{
    DoStuffWith(match.Value);
}

正则表达式之所以有效,是因为它需要匹配模式。如果你打破了模式,你就打破了对正则表达式的需求。模式是如何被打破的。模式保持不变,这是我在替换匹配项时可能破坏的源。regex提供了Replace函数,所以我不认为我否定了对regex的需求,这是我的观点。您正在破坏源代码,因此,您的模式也可能根据正则表达式引擎被破坏。
Regex.Rplace
替换所有匹配项。无需迭代到下一个。@SinaIravanian我认为OP每次都在更改源代码。。这就是我的理解?正则表达式之所以有效,是因为它需要匹配模式。如果你打破了模式,你就打破了对正则表达式的需求。模式是如何被打破的。模式保持不变,这是我在替换匹配项时可能破坏的源。regex提供了Replace函数,所以我不认为我否定了对regex的需求,这是我的观点。您正在破坏源代码,因此,您的模式也可能根据正则表达式引擎被破坏。
Regex.Rplace
替换所有匹配项