我想使用正则表达式将多个组替换为相应的替换字符串。
替换表:
"&"
->"__amp"
"#"
->"__hsh"
"1"
->"5"
"5"
->"6"
例如,对于以下输入字符串:
"a1asda&fj#ahdk5adfls"
对应的输出字符串为
"a5asda__ampfj__hshahdk6adfls"
有没有什么方法可以做到这一点?
我想使用正则表达式将多个组替换为相应的替换字符串。
替换表:
"&"
-> "__amp"
"#"
-> "__hsh"
"1"
-> "5"
"5"
-> "6"
例如,对于以下输入字符串:
"a1asda&fj#ahdk5adfls"
对应的输出字符串为
"a5asda__ampfj__hshahdk6adfls"
有没有什么方法可以做到这一点?
给定一个定义了你需要替换的字典:
IDictionary<string, string> map = new Dictionary<string, string>()
{
{"&","__amp"},
{"#","__hsh"},
{"1","5"},
{"5","6"},
};
你可以同时用它来构建正则表达式,并为每个匹配项形成替换:
var str = "a1asda&fj#ahdk5adfls";
var regex = new Regex(String.Join("|",map.Keys));
var newStr = regex.Replace(str, m => map[m.Value]);
// newStr = a5asda__ampfj__hshahdk6adfls
实时示例: http://rextester.com/rundotnet?code=ADDN57626
这使用了一个Regex.Replace
重载,它允许您指定替换的lambda表达式。
评论中指出,如果查找模式中具有正则表达式语法,则不会按预期工作。这可以通过使用Regex.Escape
和对上面的代码进行轻微更改来解决:
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
map.Keys
替换为 map.Keys.Select(s => Regex.Escape(s))
,以处理键是正则表达式敏感字符(如 +
或 *
)的情况。 - Kache给定一个类似于其他答案中的字典,您可以使用“聚合”将字典中的每个模式映射到替换内容。这将为您提供比其他答案更灵活的选择,因为您可以为每个模式设置不同的正则表达式选项。
例如,以下代码将对希腊文本进行罗马化处理(https://en.wikipedia.org/w/index.php?title=Romanization_of_Greek§ion=3#Modern_Greek, 标准/联合国):
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));
返回(不修改“input”变量):
"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);
这会修改"input"变量。
此外,您可以添加以下内容以提高性能:
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));
string.Replace()
函数?string foo = "a1asda&fj#ahdk5adfls";
string bar = foo.Replace("&","__amp")
.Replace("#","__hsh")
.Replace("5", "6")
.Replace("1", "5");
和Jamiec的答案类似,但这样可以使用不完全匹配的正则表达式,例如\.
不能与Jamiec的答案一起使用,因为你无法在字典中查找匹配项。
此解决方案依赖于创建组,查找匹配的组,然后查找替换值。它更复杂,但更灵活。
首先将映射创建为KeyValuePairs列表
var map = new List<KeyValuePair<string, string>>();
map.Add(new KeyValuePair<string, string>("\.", "dot"));
string pattern = String.Join("|", map.Select(k => "(" + k.Key + ")"));
var regex = new Regex(pattern, RegexOptions.Compiled);
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))
我想分享一下对Jamiec和Costas解决方案的经验。
如果你遇到以下问题:
字典中没有给定键“<搜索参数>”。
请记住,在字典键中放置正则表达式模式。
IDictionary<string, string> map = new Dictionary<string, string>()
{
{"(?<=KeyWord){","("},
{"}",")"}
};
并且这样使用它
var regex = new Regex(String.Join("|",map.Keys));
var newStr = regex.Replace(str, m => map[m.Value]);
var newStr = Regex.Replace(content, pattern, m => replacementMap[m.Value]);
可能会抛出上述异常,因为模式在替换比较之前被执行,只留下要与字典中的正则表达式键进行比较的匹配项。这样,键和匹配项可能不同,从而引发异常。
'(?<=KeyWord){' != '{'
这是我的解决方案:
我需要将跟在关键字后面的“{”和相应的“}”替换为“(”和“)”,使其更加通俗易懂。
简而言之,将其变为:
@"some random text KeyWord{"Value1", "Value2"} some more
random text";
转换为这样
@"some random text KeyWord('"Value1", "Value2"') some more
random text";
重要内容
IDictionary<string, string> map = new Dictionary<string, string>()
{
{"{","('"},
{"}","')"}
};
var content = @"some random text KeyWord{"Value1", "Value2"} some more
random text";
var pattern = "((?<=KeyWord){)|((?<=\")})";
var newStr = Regex.Replace(content, pattern, m => map[m.Value]);