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

标签 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);

最佳答案

这肯定是由 catastrophic backtracking 引起的,罪魁祸首是

(\s|[^H]*)*

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

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

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

关于c# - 为什么这个正则表达式模式会导致解析器在给定某些输入时挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10395361/

相关文章:

c# - 如何在远程服务器上安装 C# Windows 服务?

c# - 检索当前用户的 Active Directory 组

c# - 已接受的用于处理 Excel 数据的集合

c# - 我可以拆箱一个字符串吗?

c# - 与 NHibernate 的一对一映射/使用实体作为 PK

C#,如何使声明为对象的 int 增量?

javascript - Livecycle RegEx 字符长度错误

Javascript提取字符串中的未知数字

python - 如何概括这个正则表达式,以便它开始捕获字符串开头的子字符串或者后面跟着其他单词的子字符串?

c# - 在 Web API 中转发和存储请求流