【发布时间】:2013-05-28 18:19:30
【问题描述】:
这个问题与this one 密切相关,但它与包含对全局变量(未注释掉)的引用的抓取方法有关。
我正在使用以下正则表达式和测试字符串来检查它是否有效,但它只是部分有效:
正则表达式
^((?:(?:Public|Private)\s+)?(?:Function|Sub).+)[\s\S]+?(GLOBAL_VARIABLE_1)[\s\S]+?End\s+(?:Function|Sub)$
(我需要以这种方式与捕获组一起使用正则表达式的一部分,以便我可以获取方法的名称作为子匹配项)。
测试字符串
'-----------------------------------------------------------------------------------------
'
' the code: Header
'
'-----------------------------------------------------------------------------------------
Dim GLOBAL_VARIABLE_1
Dim GLOBAL_VARIABLE_2
Dim GLOBAL_VARIABLE_3
Public Function doThis(byVal xml)
'' Created : dd/mm/yyyy
'' Return : string
'' Param : xml- an xml blob
return = replace(xml, "><", ">" & vbLf & "<")
GLOBAL_VARIABLE_1 = 2 + 2
doThis = return
End Function
msgbox GLOBAL_VARIABLE_1
Public Function doThat(byVal xPath)
'' Created : dd/mm/yyyy
'' Return : array
' 'Param : xPath
return = split(mid(xPath, 2), "/")
GLOBAL_VARIABLE_2 = 2 + 2
doThat = return
End Function
GLOBAL_VARIABLE_2 = 2 + 2
Public Sub butDontDoThis()
'' Created : dd/mm/yyyy
'' Return : string
' 'Param : obj
For i = 0 To 5
return = return & "bye" & " "
Next
End Sub
GLOBAL_VARIABLE_3 = 3 + 3
Public Sub alsoDoThis(byRef obj)
'' Created : dd/mm/yyyy
'' Return : string
' 'Param : obj, an xml document object
For i = 0 To 4
return = return & "hi" & " "
Next
GLOBAL_VARIABLE_1 = 1 + 1
End Sub
GLOBAL_VARIABLE_3 = 3 + 3
使用http://www.regexpal.com/,我可以突出显示引用全局变量的第一个方法。但是,正则表达式并没有像我期望的那样使用其他方法。正则表达式还会选择其他没有引用特定全局变量的方法,并以最后一个实际使用全局变量的方法结束。我已经确定问题是 [\s\S]+?(GLOBAL_VARIABLE_1)[\s\S]+?End\s+(?:Function|Sub)$ 部分正在进行最小/非贪婪匹配,因此它会一直查找直到找到实际匹配。
总而言之,表达式应遵循以下规则:
- 在看到方法声明的first结尾时停止扫描当前正在检查的方法。在这个例子中,只有
doThis和alsoDoThis方法应该与GLOBAL_VARIABLE_1匹配,但我不确定正则表达式应该是什么。 - 正则表达式也应该只匹配实际使用全局变量的方法
- 如果
GLOBAL_VARIABLE_1被注释掉,那么它确实没有被该方法使用。已评论的GLOBAL_VARIABLE_1不应触发对该方法的肯定匹配。
【问题讨论】:
-
您想要的具有单个正则表达式的解决方案不容易实现,并且会产生难以维护的表达式。同样,像这样的复杂表达式可能会运行得更慢,然后简单地将逻辑包装在两个单独的正则表达式周围。这是正则表达式不是解析 HTML 等字符串的解决方案的原因之一。如果您真的对单个表达式感兴趣,那么建议您提交此内容并获得赏金,这需要您在 Stack Overflow 上获得 250 分。
标签: regex vbscript non-greedy