[英]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.