C# - 在Regex.Replace中使用matchTimeout参数

时间:2017-07-31 15:28:47

标签: c# .net regex

我有一个小的正则表达式,用空字符串替换不可打印的字符。 (XML文档中不支持的那些)

传入数据的大小非常大,因此如果此Replace花费的时间超过几毫秒,我想取消它并返回原始字符串。

下面是我的代码,但即使我提供的catch为1毫秒,我似乎无法点击Timespan块。来自stopwatch的日志显示它花费了超过10毫秒。

我在这里做错了什么?

只有在给定的时间跨度内找不到匹配项时,这是否有效?

测试此功能的最佳方法是什么?

更新 - 我使用没有任何不可打印字符的大文件(4 MB)测试了下面的正则表达式。 Regex花了79毫秒,但没有抛出异常。

  private static string CleanUpNonPrintableCharacters(string incomingString)
    {
        var stopWatch = new Stopwatch();
        try
        {
            stopWatch.Start();
            var timeSpan = TimeSpan.FromMilliseconds(1);

            var cleanedUpString = Regex.Replace(incomingString, @"[\u0000-\u0008\u000B\u000C\u000E-\u001F]", string.Empty, RegexOptions.None, timeSpan);

            stopWatch.Stop(); 
            Console.Log(stopWatch.ElapsedMilliseconds);
            //Above was 79 ms on a file that doesn't have a match, yet no exception was thrown

            if (cleanedUpString.Length < incomingString.Length)
            {
                //do some logging
            }
            return cleanedUpString;
        }
        catch (RegexMatchTimeoutException ex)
        {
            //do some logging
            return incomingString;
        }
        finally
        {
            //stopWatch.Stop();
            //log elapsed
        }
    }

2 个答案:

答案 0 :(得分:2)

The manual states

  

matchTimeout参数指定模式匹配方法在超时前应尝试查找匹配的时间。设置超时间隔可防止依赖于过度回溯的正则表达式在处理包含近匹配的输入时停止响应。

我认为它发现下一个匹配的速度超过1毫秒,但是有很多匹配,所以它会加起来。

答案 1 :(得分:2)

从我的理解来看,timeout仅用于匹配模式,而不是使用超时来替换匹配的字符。

如果您查看Regex source code,这里是使用超时来查找匹配的代码:

  match = runner.Scan(this, input, beginning, beginning + length,
               startat, prevlen, quick, internalMatchTimeout);.// runner is RegexRunner instance

因此,Regex.Replace包含匹配方法和替换方法。在您的情况下,匹配非常快,因此它不会抛出RegexMatchTimeoutException异常,但替换给定匹配的方法似乎很慢。

我最后没有测试过,但您只能调用Match方法进行测试并查看结果