为什么这个正则表达式模式会导致解析器在给定某些输入时挂起?

时间:2012-05-01 08:33:27

标签: c# .net regex

我有一个解析TNS名称文件的正则表达式。但它挂起在某些TNSNames文件上。问题已被追溯到匹配的字符串是否在HOST=部分之后有空格。忽略模式的适当性,以及如何解决问题(已经处理过)我想知道的是为什么输入的改变会导致应用程序挂起,因为Regex.Match(invalid)调用永远不会返回

string valid = "SOMENAME = (DESCRIPTION= " + 
                "(ADDRESS= (PROTOCOL=TCP) (HOST = localhost) (PORT=1521) ) " + 
                "(CONNECT_DATA= (SERVICE_NAME=ABC)))";

string invalid = "SOMENAME = (DESCRIPTION= " + 
                "(ADDRESS= (PROTOCOL=TCP) (HOST =localhost) (PORT=1521) ) " + 
                "(CONNECT_DATA= (SERVICE_NAME=ABC)))";
Regex regex = new Regex("SOMENAME" + @"[^=]*=(\s|[^H]*)*HOST\s*=\s(?<host>[^\)]*)\s*\)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
//this line is fine
Match match = regex.Match(valid);  
//this line causes visual studio to hang
match = regex.Match(invalid);

1 个答案:

答案 0 :(得分:4)

这肯定是由catastrophic backtracking造成的,罪魁祸首是

(\s|[^H]*)*

因为\s[^H]可以匹配相同的内容,并且因为您嵌套了两个无限量词。

[^H]*匹配完全相同的内容,并且不容易回溯,所以试试这个:

Regex regex = new Regex("SOMENAME" + @"[^=]*=([^H]*)HOST\s*=\s(?<host>[^\)]*)\s*\)", RegexOptions.Multiline | RegexOptions.IgnoreCase);