为什么这种正则表达式模式会导致解析器在给定特定输入的情况下挂起

本文关键字:输入 挂起 情况下 正则表达式 模式 为什么 | 更新日期: 2023-09-27 18:32:44

我有一个解析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);

为什么这种正则表达式模式会导致解析器在给定特定输入的情况下挂起

这肯定是由灾难性的回溯引起的,罪魁祸首是

('s|[^H]*)*

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

[^H]*单独匹配完全相同的内容,并且不容易回溯,因此请尝试以下操作:

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