匹配和替换多个正则表达式的最快方法

本文关键字:方法 正则表达式 替换 | 更新日期: 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集合中总是最后一个。