簡體   English   中英

隨機 RegexMatchTimeoutException 異常

[英]Random RegexMatchTimeoutException exceptions

在解析短(少於 100 個字符)字符串時,我有時會遇到RegexMatchTimeoutException 解析本身位於 function 中的list.Select(..)中,該集合包含大約 30 個元素。

我懷疑這可能是由於次優正則表達式 - 這是 C# 中的定義:

internal override Regex Regex => new(
    @$"((.|\s)*\S(.|\s)*)(\[{this.Type}\])",             // Type = "input"
    RegexOptions.Multiline | RegexOptions.Compiled, 
    TimeSpan.FromMilliseconds(Constants.RegexTimeout));  // RegexTimeout = 100

它應該捕獲以下字符串中的Sample text

Sample text
[input]

完整異常消息:

System.Text.RegularExpressions.RegexMatchTimeoutException: 'The Regex engine has timed out while trying to match a pattern to an input string. This can occur for many reasons, including very large inputs or excessive backtracking caused by nested quantifiers, back-references and other factors.'

發生異常的行:

var label = this.Regex.Match(sectionContent).Groups[1].Value.Trim();

異常很難重現——使用相同的輸入,它可能在第一次運行或第 100 次運行時發生。 但是運行正則表達式的行集合越大,它發生的可能性就越大。

您的((.|\s)*\S(.|\s)*)(\[input\])正則表達式匹配

  • ((.|\s)*\S(.|\s)*) - 第 1 組:
    • (.|\s)* - 除換行符 ( . ) 或 ( | ) 以外的任何字符出現零次或多次,任何空白字符 ( \s )
    • \S - 非空白字符
    • (.|\s)* - 除換行符 ( . ) 或 ( | ) 以外的任何字符出現零次或多次,任何空白字符 ( \s )
  • (\[input\]) - 第 2 組: [input]

您不得不注意到第 1 組模式中的每一個都可以匹配相同的字符。 \S是這里唯一的“錨定”模式,它需要一個非空白字符,並且由於\S之前和之后的模式都用於匹配任何文本,因此最有效的邏輯是:匹配任意數量的空白,然后非空白字符,然后是任意數量的字符(盡可能少但盡可能多)直到[input]

這是修復:

internal override Regex Regex => new(
    @$"(?s)(\s*\S.*?)(\[{Regex.Escape(this.Type)}])",             // Type = "input"
    RegexOptions.Compiled, 
    TimeSpan.FromMilliseconds(Constants.RegexTimeout));  // RegexTimeout = 100`

請注意,可以轉義this.Type以防萬一其中有任何特殊字符。 (?s)RegexOptions.Singleline選項的內聯修飾符版本(可互換使用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM