我的.NET Regex.Match可能因为回溯而挂起

时间:2015-05-06 15:13:31

标签: c# .net regex

当我的正则表达式无法找到匹配项时,我的应用程序会永远挂起。我正在尝试匹配下面的文本部分(实际数字已被字母替换)。

JIBBERISHNESS           JABBERISHNESS             JIBBERISHNESS                    
          YEAR                  DOLLARAMT            JABBERISHNESS                  
           A                   $XX,XXX.XX         $X,XXX,XXX                      
           B                    XX,XXX.XX         JIBBERISHNESS              
           C                    XX,XXX.XX           JABBERISHNESS                 
           D                    XX,XXX.XX                                         
           E                    XX,XXX.XX                                         
           F                    XX,XXX.XX                                         
          GG                    XX,XXX.XX                                         
          HH                   XXX,XXX.XX                                         
          KK                   XXX,XXX.XX                                         
      AGE YY                    XX,XXX.XX                                         
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -           
 0000-HOME OFFIC                  LAST PAGE                        PAGE  3       { 

我有多个正则表达式

string YearARegex = @" +A +\$(?<dollarAmtA>(\d{1,3},?)+\.\d\d).*\n";
string YearBRegex = YearARegex + @" +B +(?<dollarAmtB>(\d{1,3},?)+\.\d\d).*\n";
string YearCRegex = YearBRegex + @" +C +(?<dollarAmtC>(\d{1,3},?)+\.\d\d).*\n";

建立在前一行的前一个正则表达式之上。但是,我的应用程序依赖于此正则表达式:

string AgeXXRegex = YearKKRegex + @" +AGE XX +(?<premiumXX>(\d{1,3},?)+\.\d\d) +\n";
我搜索了症状,我最好的猜测是因为'灾难性的回溯'。有人能证实吗?目标文本看起来并不那么大,我正在使用的复合正则表达式似乎足够具体(至少对我来说是人类)。

有人可以推荐一种解决方案来阻止应用程序挂起吗?

1 个答案:

答案 0 :(得分:0)

在具有超时的单独线程中运行正则表达式匹配:

var tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
int timeOut = 500; // 500 ms

var task = Task.Factory.StartNew(() => {
  return YearARegex + @" +B +(?<dollarAmtB>(\d{1,3},?)+\.\d\d).*\n"; 
}, token);

if (!task.Wait(timeOut, token))
    Console.WriteLine("The Task timed out!");

任务执行的结果将在task.Result属性中。 此外,我会尝试结合更优化的正则表达式,至少使用

^   Start of line
$   End of line