C# 正则表达式:命名组和替换

C# 正则表达式:命名组和替换,c#,.net,regex,C#,.net,Regex,有一种方法 Regex.Replace(string source, string pattern, string replacement) 最后一个参数支持模式替换,例如${groupName}和其他(但我不知道运行时的组名) 在我的例子中,我有动态创建的模式,如: (?<c0>word1)|(?<c1>word2)|(?<c2>word3) (?word1)|(?word2)|(?word3) 我的目的是根据组名用值替换每个组。例如,单词“word1

有一种方法

Regex.Replace(string source, string pattern, string replacement)
最后一个参数支持模式替换,例如
${groupName}
和其他(但我不知道运行时的组名)

在我的例子中,我有动态创建的模式,如:

(?<c0>word1)|(?<c1>word2)|(?<c2>word3)
(?word1)|(?word2)|(?word3)
我的目的是根据组名用值替换每个组。例如,单词“word1”将替换为
word1
。这是为了突出显示像谷歌这样的搜索结果

是否可以使用上面的方法而不使用带有
MatchEvaluator
参数的重载方法来执行此操作


提前谢谢

我不认为以您建议的方式使用${groupname}是可行的,除非我误解了正在执行的确切替换。原因是替换字符串的构造方式必须确保它能够解释每个组名。因为它们是动态生成的,所以这不可能实现。换句话说,在1语句中,您如何设计一个替换字符串来覆盖c0…cn并替换它们各自的捕获值?您可以循环浏览这些名称,但如何保持修改后的文本完整,以便对每个groupname执行1次替换

不过我有一个可能的解决办法。它仍然使用MatchEvaluator重载,但是使用一些lambda表达式和LINQ,您可以将其减少到1行。不过,为了清晰起见,我将在下面对其进行格式化。也许这会符合你的需要,或者为你指明正确的方向

string text = @"The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.";
string[] searchKeywords = { "quick", "fox", "lazy" };

// build pattern based on keywords - you probably had a routine in place for this
var patternQuery = searchKeywords
                        .Select((s, i) => 
                            String.Format("(?<c{0}>{1})", i, s) +
                            (i < searchKeywords.Length - 1 ? "|" : ""))
                        .Distinct();
string pattern = String.Join("", patternQuery.ToArray());
Console.WriteLine("Dynamic pattern: {0}\n", pattern);

// use RegexOptions.IgnoreCase for case-insensitve search
Regex rx = new Regex(pattern);

// Notes:
// - Skip(1): used to ignore first groupname of 0 (entire match)
// - The idea is to use the groupname and its corresponding match. The Where
//   clause matches the pair up correctly based on the current match value
//   and returns the appropriate groupname
string result = rx.Replace(text, m => String.Format(@"<span class=""{0}"">{1}</span>", 
                    rx.GetGroupNames()
                    .Skip(1)
                    .Where(g => m.Value == m.Groups[rx.GroupNumberFromName(g)].Value)
                    .Single(),
                    m.Value));

Console.WriteLine("Original Text: {0}\n", text);
Console.WriteLine("Result: {0}", result);
string text=@“敏捷的棕色狐狸跳过了懒狗。敏捷的棕色狐狸跳过了懒狗。”;
string[]searchKeywords={“quick”、“fox”、“lazy”};
//基于关键字构建模式-您可能已经为此准备了一个例程
var patternQuery=搜索关键字
.选择((s,i)=>
String.Format((?{1})”,i,s)+
(istring.Format(@“{1}”),
rx.GetGroupNames()
.Skip(1)
其中(g=>m.Value==m.Groups[rx.GroupNumberFromName(g)].Value)
.Single(),
m、 价值);
WriteLine(“原始文本:{0}\n”,Text);
WriteLine(“结果:{0}”,Result);
输出:

Dynamic pattern: (?<c0>quick)|(?<c1>fox)|(?<c2>lazy)

Original Text: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.

Result: The <span class="c0">quick</span> brown <span class="c1">fox</span> jumps over the <span class="c2">lazy</span> dog. The <span class="c0">quick</span> brown <span class="c1">fox</span> jumps over the <span class="c2">lazy</span> dog.
动态模式:(?快)|(?狐)|(?懒)
原文:敏捷的棕色狐狸跳过了懒狗。敏捷的棕色狐狸跳过了懒狗。
结果:敏捷的棕色狐狸跳过了懒惰的狗。敏捷的棕色狐狸跳过了懒狗。

我会选择MatchEvaluator。。。它很有效…是的,谢谢!实际上我有一个MatchEvaluator的有效解决方案。但是,一个只有一行代码而不是六行代码的解决方案是多么优雅:)谢谢!我已经用这种方式解决了我的问题。但在“一行”术语下,我的意思是类似Regex.Replace(字符串源、字符串模式“$&”)的东西。其中${groupName}是一个虚构的组名替换(但当组名已知时,它会起作用;)。但就我而言,这似乎是不可能的。再次感谢你的回答!