替换多个正则表达式匹配项,每个匹配项都用不同的替换方式进行替换。

10

我有一个字符串,可能包含一个或多个指定模式的匹配项。

每个匹配项都需要被替换。

我有以下代码:

var pattern = @"\$\$\@[a-zA-Z0-9_]*\b";
var stringVariableMatches = Regex.Matches(strValue, pattern);
var sb = new StringBuilder(strValue);

foreach (Match stringVarMatch in stringVariableMatches)
{
    var stringReplacment = variablesDictionary[stringVarMatch.Value];
    sb.Remove(stringVarMatch.Index, stringVarMatch.Length)
            .Insert(stringVarMatch.Index, stringReplacment);
}

return sb.ToString();
当我有几个匹配项时,问题在于第一个被替换,其余的起始索引也随之改变,因此在某些情况下,在字符串缩短后进行替换时,会出现索引超出范围的情况。
我知道我可以对每个匹配项使用Regex.Replace,但这可能会影响性能,并希望看看是否有其他解决方案来替换多个匹配项,每个匹配项都有不同的字符串。

Regex.Replace对于每个匹配都进行替换,但这会导致性能负担。你的数据有多大? - Thomas Ayoub
我有大约10万个这样的字符串要迭代处理...每个字符串可能有1-3个匹配项需要用不同的字符串替换。 - Mortalus
@LucasTrzesniewski:我认为Mortalus的意思是在foreach内部使用Regex.Replace会影响性能。关键是Regex.Replace可以代替Regex.Matches使用。 - Wiktor Stribiżew
@WiktorStribiżew 是的,我认为我误解了他的意图(他对你的答案的评论证实了这一点)。 - Lucas Trzesniewski
1个回答

23

Regex.Replace中使用匹配评估器:

var pattern = @"\$\$\@[a-zA-Z0-9_]*\b";
var stringVariableMatches = Regex.Replace(strValue, pattern, 
        m => variablesDictionary[m.Value]);
Regex.Replace 方法将执行全局替换,即查找所有与指定模式匹配且不重叠的子字符串,并将每个找到的匹配值替换为 variablesDictionary[m.Value]。请注意,最好检查字典中是否存在键

参见C#演示

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;
public class Test
{
    public static void Main()
    {
        var variablesDictionary = new Dictionary<string, string>();
        variablesDictionary.Add("$$@Key", "Value");
        var pattern = @"\$\$@[a-zA-Z0-9_]+\b";
        var stringVariableMatches = Regex.Replace("$$@Unknown and $$@Key", pattern, 
                m => variablesDictionary.ContainsKey(m.Value) ? variablesDictionary[m.Value] : m.Value);
        Console.WriteLine(stringVariableMatches);
    }
}

输出: $$ @Unknown and Value


1
没问题,我会仔细研究个人资料,查看有趣的内容,然后投票支持值得支持的内容。很少情况下,我要说:从未,系统会认定我的活动是“连续投票”;-) - GhostCat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接