Jam*_*iec 41
给定一个定义替换的字典:
IDictionary<string,string> map = new Dictionary<string,string>()
{
{"&","__amp"},
{"#","__hsh"},
{"1","5"},
{"5","6"},
};
Run Code Online (Sandbox Code Playgroud)
您可以使用它来构建正则表达式,并为每个匹配形成替换:
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
Run Code Online (Sandbox Code Playgroud)
实例:http://rextester.com/rundotnet?code = ADDN57626
这使用Replace(docs)重载,允许您为替换指定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
Run Code Online (Sandbox Code Playgroud)
怎么用string.Replace()?
string foo = "a1asda&fj#ahdk5adfls";
string bar = foo.Replace("&","__amp")
.Replace("#","__hsh")
.Replace("5", "6")
.Replace("1", "5");
Run Code Online (Sandbox Code Playgroud)
与Jamiec的答案类似,但这允许您使用与文本不完全匹配的正则表达式,例如\.不能与Jamiec的答案一起使用,因为您无法在字典中查找匹配项。
该解决方案依赖于创建组,查找匹配的组,然后查找替换值。它更复杂,但更灵活。
首先将地图设为KeyValuePairs列表
var map = new List<KeyValuePair<string, string>>();
map.Add(new KeyValuePair<string, string>("\.", "dot"));
Run Code Online (Sandbox Code Playgroud)
然后像这样创建你的正则表达式:
string pattern = String.Join("|", map.Select(k => "(" + k.Key + ")"));
var regex = new Regex(pattern, RegexOptions.Compiled);
Run Code Online (Sandbox Code Playgroud)
然后匹配评估器变得有点复杂:
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");
}
Run Code Online (Sandbox Code Playgroud)
然后像这样调用正则表达式替换:
var newString = regex.Replace(text, m => Evaluator(map, m))
Run Code Online (Sandbox Code Playgroud)
给定其他答案中的字典,您可以使用“聚合”将字典中的每个模式映射到替换。这将为您提供比其他答案更大的灵活性,因为您可以为每个模式使用不同的正则表达式选项。
例如,以下代码将“罗马化”希腊文本(https://en.wikipedia.org/w/index.php?title=Romanization_of_Greek§ion=3#Modern_Greek , Standard/UN):
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));
Run Code Online (Sandbox Code Playgroud)
返回(不修改“输入”变量:
"o kalymnios sfoungaras psythirise pos tha voutixei choris na distazei."
Run Code Online (Sandbox Code Playgroud)
你当然可以使用类似的东西:
foreach (var m in map) input = Regex.Replace(input, m.Key, m.Value, RegexOptions.IgnoreCase);
Run Code Online (Sandbox Code Playgroud)
这确实修改了“输入”变量。
您也可以添加它以提高性能:
var remap = new Dictionary<Regex, string>();
foreach (var m in map) remap.Add(new Regex(m.Key, RegexOptions.IgnoreCase | RegexOptions.Compiled), m.Value);
Run Code Online (Sandbox Code Playgroud)
缓存或使重映射字典静态化,然后使用:
remap.Aggregate(input, (i, m) => m.Key.Replace(i, m.Value));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18237 次 |
| 最近记录: |