我有下一个正则表达式
Dim origen As String = " /c /p:""c:\mis doc umentos\mis imagenes construida\archivo.txt"" /cid:45 423 /z:65 /a:23 /m:39 /t:45rt "
Dim str As String = "(^|\s)/p:""\w:(\\(\w+[\s]*\w+)+)+\\\w+.\w+""(\s|$)"
Dim ar As Integer
Dim getfile As New Regex(str)
Dim mgetfile As MatchCollection = getfile.Matches(origen)
ar = mgetfile.Count
当我对此进行评估时,它会起作用,并获取/p:""c:\mis doc umentos\mis imagenes construida\archivo.txt""
,它基本上是文件的路径。
但是如果我将origen字符串更改为
Dim origen As String = " /c /p:""c:\mis doc umentos\mis imagenes construida\archivo.txt""/cid:45 423 /z:65 /a:23 /m:39 /t:45rt "
检查文件的末尾是否后面跟着“/ cid:45”whitch使得de pattern无效,但是没有得到mgetfile.count = 0,程序就是阻塞,如果我进行调试我得了一个 财产评估失败。
答案 0 :(得分:2)
你可以将整个表达式清理为:
str = "/p:"".*?"""
答案 1 :(得分:1)
您的程序挂起的原因是catastrophic backtracking。
正则表达式(\w+\s*\w+)+
和\w+.\w+
的部分允许这么多的排列,以便正则表达式引擎陷入近无限循环。 RegexBuddy的调试器在1000000步后退出。
仅当模式无法成功匹配时才会发生这种情况,从而提示正则表达式引擎尝试模式允许的任何和所有其他排列。通常,重复包含重复量词的组是危险的。
真正的要求是什么?匹配仅包含字母,数字,下划线和反斜杠的路径?或者只是引号之间的字符串?也许你可以对此有所了解......
在此之前,我建议如下:
"(?<=^|\s)/p:""\w:(\\[\w\s]++)+\.\w+""(?=\s|$)"
这清除了一些内容:(\\[\w\s]++)
匹配反斜杠,后跟任意数量的字母数字和空格字符。一旦匹配,正则表达式引擎拒绝尝试不同的排列(这可以通过使用可能的量词++
而不仅仅是+
来实现。
之后,它匹配一个点(您的版本将匹配任何字符)和一系列字母数字字符。然后是引号,然后检查是否有空格或字符串结尾。如果没有,正则表达式将失败,并迅速失败。
如果您只想在引号之间匹配字符串,那么
"(?<=^|\s)/p:""[^""]+""(?=\s|$)"
是最好最快的方式。
答案 2 :(得分:0)
您是否始终知道开头和结尾有两个双引号?如果是这样的话:
(^|\s)/p:""(.*?)""(.*$)