C# 正则表达式替换多个组

C# 正则表达式替换多个组,c#,.net,regex,replace,C#,.net,Regex,Replace,我想使用正则表达式用相应的替换字符串替换多个组 替换表: “&”->“\uu amp” “#”->“uu-hsh” “1”->“5” “5”->“6” 例如,对于以下输入字符串 "a1asda&fj#ahdk5adfls" 相应的输出字符串为 "a5asda__ampfj__hshahdk6adfls" 有办法吗?使用string.Replace()怎么样 给定定义替换项的词典: IDictionary<string, string> map = new Dictio

我想使用正则表达式用相应的替换字符串替换多个组

替换表:

  • “&”
    ->
    “\uu amp”
  • “#”
    ->
    “uu-hsh”
  • “1”
    ->
    “5”
  • “5”
    ->
    “6”
例如,对于以下输入字符串

"a1asda&fj#ahdk5adfls"
相应的输出字符串为

"a5asda__ampfj__hshahdk6adfls"

有办法吗?

使用
string.Replace()
怎么样


给定定义替换项的词典:

IDictionary<string, string> map = new Dictionary<string, string>()
{
    {"&","__amp"},
    {"#","__hsh"},
    {"1","5"},
    {"5","6"},
};
实例:

这使用了一个重载,允许您为替换指定lambda表达式


在评论中已经指出,一个包含正则表达式语法的find模式将不能像预期的那样工作。这可以通过使用和对上述代码进行细微更改来克服:

var str = "a1asda&fj#ahdk5adfls";
var regex = new Regex(String.Join("|",map.Keys.Select(k => Regex.Escape(k))));
var newStr = regex.Replace(str, m => map[m.Value]);
// newStr = a5asda__ampfj__hshahdk6adfls

与Jamiec的答案类似,但这允许您使用与文本不完全匹配的正则表达式,例如,
\。
不能与Jamiec的答案一起使用,因为您无法在字典中查找匹配项

此解决方案依赖于创建组,查找匹配的组,然后查找替换值。这是一个更复杂但更灵活的方法

首先使映射成为KeyValuePairs的列表

var map = new List<KeyValuePair<string, string>>();           
map.Add(new KeyValuePair<string, string>("\.", "dot"));
然后,匹配计算器变得有点复杂:

private static string Evaluator(List<KeyValuePair<string, string>> map, Match match)
{            
    for (int i = 0; i < match.Groups.Count; i++)
    {
        var group = match.Groups[i];
        if (group.Success)
        {
            return map[i].Value;
        }
    }

    //shouldn't happen
    throw new ArgumentException("Match found that doesn't have any successful groups");
}

给定与其他答案类似的字典,可以使用“聚合”将字典中的每个模式映射到替换模式。这将为您提供比其他答案更大的灵活性,因为您可以为每个模式提供不同的正则表达式选项

例如,以下代码将“罗马化”希腊文本(,标准/UN):

当然,您可以使用以下内容:

foreach (var m in map) input = Regex.Replace(input, m.Key, m.Value, RegexOptions.IgnoreCase);
它会修改“输入”变量

您还可以添加以下内容以提高性能:

var remap = new Dictionary<Regex, string>();
foreach (var m in map) remap.Add(new Regex(m.Key, RegexOptions.IgnoreCase | RegexOptions.Compiled), m.Value);

见鬼,我觉得这比我的好,但是OP要求使用正则表达式,现在OP有两个问题:)Jamice:你明白了!:)您的答案很好,如果项目列表来自某个源(文件、数据库等),则可以进行扩展,而我的答案是硬编码的,需要更改时需要重新编译。这只适用于您重新排序了5->6和1->5,实际上,你可以有1->5和5->1,但这是行不通的。雷:那是故意的。我对解决方案进行了编码以确保其有效。你说它“只起作用”是什么意思?这是一个简单的字符串替换。有很多方法可以对其进行编码,这样“它就不起作用了”。我构造了一个答案,使它在一段时间内有效。你的意思是什么?我运气好还是怎么了?我假设表和字符串只是示例,在实际程序中,替换模式(以及输入字符串)将是参数。但是,您仍然应该转义字符串。如果要替换的令牌之一是
$
,该怎么办?请参阅我的答案,其中对此进行了扩展,以使其更灵活(因此您可以使用更多的正则表达式语法)。进行了编辑,但正在等待同行审查。将
map.Keys
替换为
map.Keys.Select(s=>Regex.Escape(s))
以处理密钥是Regex敏感字符的情况,如
+
*
@Kache-谢谢,我认为您的编辑非常好,但似乎被拒绝了。我可能会在自己身上编辑类似的内容,但只是作为脚注,而不是对实际代码的更改。谢谢,但我输入的“Hello[[Salitation]][[firstname][[lastname]]”会给出输出“Hello Dr.”。映射是:map.Add(newkeyvaluepair(@“[{2}称呼]{2}”,“Dr.”);Add(新的KeyValuePair(@“[{2}firstname]{2}”,“John”);Add(新的KeyValuePair(@“[{2}lastname]{2}”,“Doe”);非常优雅的最终解决方案。
private static string Evaluator(List<KeyValuePair<string, string>> map, Match match)
{            
    for (int i = 0; i < match.Groups.Count; i++)
    {
        var group = match.Groups[i];
        if (group.Success)
        {
            return map[i].Value;
        }
    }

    //shouldn't happen
    throw new ArgumentException("Match found that doesn't have any successful groups");
}
var newString = regex.Replace(text, m => Evaluator(map, m))
var map = new Dictionary<string,string>() {
    {"α[ύυ](?=[άαβγδέεζήηίΐϊιλμνόορύΰϋυώω])", "av"}, {"α[ύυ]", "af"}, {"α[ϊΐ]", "aï"}, {"α[ιί]", "ai"}, {"[άα]", "a"},
    {"β", "v"}, {"γ(?=[γξχ])", "n"}, {"γ", "g"}, {"δ", "d"},
    {"ε[υύ](?=[άαβγδέεζήηίΐϊιλμνόορύΰϋυώω])", "ev"}, {"ε[υύ]", "ef"}, {"ει", "ei"}, {"[εέ]", "e"}, {"ζ", "z"},
    {"η[υύ](?=[άαβγδέεζήηίΐϊιλμνόορύΰϋυώω])", "iv"}, {"η[υύ]", "if"}, {"[ηήιί]", "i"}, {"[ϊΐ]", "ï"},
    {"θ", "th"}, {"κ", "k"}, {"λ", "l"}, {"\\bμπ|μπ\\b", "b"}, {"μπ", "mb"}, {"μ", "m"}, {"ν", "n"},
    {"ο[ιί]", "oi"}, {"ο[υύ]", "ou"}, {"[οόωώ]", "o"}, {"ξ", "x"}, {"π", "p"}, {"ρ", "r"},
    {"[σς]", "s"}, {"τ", "t"}, {"[υύϋΰ]", "y"}, {"φ", "f"}, {"χ", "ch"}, {"ψ", "ps"}
};

var input = "Ο Καλύμνιος σφουγγαράς ψυθίρισε πως θα βουτήξει χωρίς να διστάζει."; 
map.Aggregate(input, (i, m) => Regex.Replace(i, m.Key, m.Value, RegexOptions.IgnoreCase));
"o kalymnios sfoungaras psythirise pos tha voutixei choris na distazei."
foreach (var m in map) input = Regex.Replace(input, m.Key, m.Value, RegexOptions.IgnoreCase);
var remap = new Dictionary<Regex, string>();
foreach (var m in map) remap.Add(new Regex(m.Key, RegexOptions.IgnoreCase | RegexOptions.Compiled), m.Value);
remap.Aggregate(input, (i, m) => m.Key.Replace(i, m.Value));