匹配和替换多个正则表达式的最快方法
本文关键字:方法 正则表达式 替换 | 更新日期: 2023-09-27 18:24:47
我知道有很多替换固定字符串的好方法,但当我有数百万个字符串时,匹配和替换许多正则表达式的最快方法是什么?
我目前正在做这个:
class Program
{
static IDictionary<string, string> _map = new Dictionary<string, string>() {
{"(AM)|(PM)", "<time>"},
// ... 20 more
{"''.[0-9]{3}", "<ms>"},
{"[a-z0-9]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}", "<guid>"},
{"_''d+_", "_<number>_"}
};
static Regex regex = new Regex(String.Join("|", _map.Keys), RegexOptions.Compiled);
static void Main(string[] args) {
// for loop for a million strings
replace("String here");
}
public static replace(string str) {
return regex.Replace(str, m => "<T>")
}
}
我无法用我想要的字符串替换,所以我使用<T>
。
以下是您的更换问题的解决方案:
private static Func<string, string> CreateReplaceFn()
{
var map = new List<Tuple<string, string>>
{
Tuple.Create("AM|PM", "<time>"),
// ... 20 more
Tuple.Create("''.[0-9]{3}", "<ms>"),
Tuple.Create("[a-z0-9]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}", "<guid>"),
Tuple.Create("_''d+_", "_<number>_")
};
var reStr = String.Join("|", map.Select(r => "(" + r.Item1 + ")"));
var regex = new Regex(reStr, RegexOptions.Compiled);
return str => regex.Replace(str, match =>
{
for (var i = 1; i <= match.Groups.Count; ++i)
{
if (match.Groups[i].Success)
return map[i - 1].Item2;
}
return match.Value;
});
}
此函数将返回一个执行所有替换的函数。您必须缓存此调用的结果,并将其重新用于替换。例如:
var replaceFn = CreateReplaceFn();
foreach (var str in myMilionStrings)
yield return replaceFn(str);
不过有一点需要注意:您不能在模式中使用未命名的捕获组。如果您必须使用组但不需要捕获,请替换所有(
。。。)
与(?:
。。)
。
如果您真的需要在模式中使用捕获组,则必须将它们命名为((?<name>)
,然后是'k<name>
来引用它)。这仍然有效,因为命名组在Match.Groups
集合中总是最后一个。