regex 在MsgBox中查找带有字符串文字的文本行,并使用正则表达式

xv8emn3q  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(80)

我想知道工作簿的模块中是否存在某种格式的代码行,在本例中是一个带有字符串文字的MsgBox。
找到pattern1,但即使pattern2存在于模块中也找不到。
Pattern1匹配带有字符串文字的MsgBox,带有左括号和右括号(),例如:

testString = MsgBox("Do you want to open our product page?", vbInformation + vbYesNoCancel, "myMessageBox")
testString = MsgBox("Do you want to open our product page?", vbYesNoCancel, "myMessageBox")
testString = MsgBox("Do you want to open our product page?", vbYesNoCancel)
testString = MsgBox("Do you want to open our product page?")

字符串
Pattern2匹配带有字符串文字的MsgBox,不带左括号和右括号(),例如:

MsgBox "Do you want to open our product page?", vbInformation + vbYesNoCancel, "myMessageBox"
MsgBox "Do you want to open our product page?", vbInformation + vbYesNoCancel
MsgBox "Do you want to open our product page?"
' Matches strings in all VBA modules of the specified workbook
' Add a reference to "Microsoft VBScript Regular Expressions 5.5" for early binding

Public Sub FindStringsInModules(ByVal objWorkbookToObfuscate As Workbook)
    Dim vbComp As Object
    Dim lineNum As Long
    Dim lineText As String
    Dim newLineText As String
    
    ' Iterate over all VBA modules in the provided workbook
    For Each vbComp In objWorkbookToObfuscate.VBProject.VBComponents
        ' Process each line in the module
        Dim lineCount As Long
        lineCount = vbComp.codeModule.CountOfLines
        For lineNum = 1 To lineCount
            lineText = vbComp.codeModule.Lines(lineNum, 1)
            newLineText = MatchLine(lineText)
            vbComp.codeModule.ReplaceLine lineNum, newLineText
        Next lineNum
    Next vbComp
End Sub

Function MatchLine(ByVal lineText As String) As String
    Dim regex As RegExp
    Set regex = New RegExp
    Dim pattern1 As String
    Dim pattern2 As String
    Dim pattern3 As String

    ' Pattern 1: Matches MsgBox with string literals, with opening and closing parenthesis ( )
    pattern1 = "(?:[a-zA-Z0-9]+\s*=\s*)?MsgBox\s*\(\s*(""[^""]*"")(?:\s*,\s*[^,)]+(?:\s*\+\s*[^,)]+)*)?(?:\s*,\s*""[^""]*"")?\s*\)"
    ' Pattern 2: Matches MsgBox without parentheses, including additional parameters and concatenations
    pattern2 = "MsgBox\s+""""[^""""]*""""(?:\s*&\s*""""[^""""]*""""|[^""""])*(?:\s*,\s*[^,""""]+)*"
    pattern3 = "MsgBox\(""[^""]*""\)\s*"

    ' Combine patterns using alternation operator
    regex.Pattern = pattern1 & "|" & pattern2 & "|" & pattern3
    regex.Global = True
    regex.MultiLine = True

    Dim matches As MatchCollection
    Set matches = regex.Execute(lineText)

    ' Process each match for potential transformation
    If matches.Count > 0 Then
        Dim match As match
        For Each match In matches
            Dim literal As String
            literal = match.SubMatches(0)
            If literal = "" Then
               Debug.Print "lineText not catched:" & lineText
               'Stop
            End If
        Next match
    End If

    MatchLine = lineText
End Function

的数据
match.SubMatches(0)返回literal = "",即使matches.Count > 0
P.S.当测试一个字符串时,MsgBox行需要用双引号括起来,内部双引号加倍,例如testString = "MsgBox ""Do you want to open our product page?"""
当测试一行HTML代码(不是字符串文字)时,MsgBox行将显示为直接写入代码中,例如MsgBox "Do you want to open our product page?"

guz6ccqo

guz6ccqo1#

如果有匹配,Regex.Test(Text)返回true。下面是我如何重构代码:

Sub ExampleUsage()
    Const Pattern1 As String = "(?:[a-zA-Z0-9]+\s*=\s*)?MsgBox\s*\(\s*(""[^""]*"")(?:\s*,\s*[^,)]+(?:\s*\+\s*[^,)]+)*)?(?:\s*,\s*""[^""]*"")?\s*\)"
    Const Pattern2 As String = "MsgBox\s+""""[^""""]*""""(?:\s*&\s*""""[^""""]*""""|[^""""])*(?:\s*,\s*[^,""""]+)*"
    Const Pattern3 As String = "MsgBox\(""[^""]*""\)\s*"
    Dim MasterPattern As String
    MasterPattern = Join(Pattern1, Pattern2, Pattern3)
    
    
    Const NewText As String = "MsgBox(""Sample Text"")"
    
    Dim Patterns() As Variant
    Patterns = Array(Pattern1, Pattern2, Pattern3)
    
    ReplaceMatchesInModule ThisWorkbook, NewText, MasterPattern
End Sub

Public Sub ReplaceMatchesInModule(ByVal objWorkbookToObfuscate As Workbook, NewText As String, Pattern As String)
    Rem Requires the reference to "Microsoft Visual Basic for Applications Extensibility #.#" library
    Dim Component As VBComponent
    Dim CodeModule As CodeModule
    Dim lineNum As Long
    Dim lineText As String

    ' Iterate over all VBA modules in the provided workbook
    For Each vbComp In objWorkbookToObfuscate.VBProject.VBComponents
        ' Process each line in the module
        Dim lineCount As Long
        lineCount = Component.CodeModule.CountOfLines
        For lineNum = 1 To lineCount
            Set CodeModule = Component.CodeModule
            lineText = CodeModule.Lines(lineNum, 1)
            
            If RegExMatch(Pattern) Then
                CodeModule.ReplaceLine lineNum, NewText
            End If
        Next lineNum
    Next vbComp
End Sub

Public Function RegExMatch(Text As String, GlobalMatch As Boolean, Multiline As Boolean, ByRef Patterns() As Variant)
    Rem Requires the reference to "Microsoft VBScript Regular Expressions 5.5" library
    Dim Regex As New RegExp
    Regex.Global = GlobalMatch
    Regex.Multiline = Multiline
    
    Dim Pattern As Variant
    For Each Pattern In Patterns
        If Regex.Test(Text) Then
            RegExMatch = True
            Exit Function
        End If
    Next
End Function

字符串
测试正则表达式是乏味的。regex101.com是一个流行的测试网站。
表情:
(?:[a-zA-Z0-9]+\s*=\s*)?MsgBox\s*(\s*(“[^"]”)(?:\s,\s*[^,)]+(?:\s*+\s*[^,)]+))?(?:\s,\s*"[^"]”)?\s)|MsgBox\s+""[^"“]""(?:\s&\s*""[^""]””|[^""])(?:\s*,\s*[^,""]+)| MsgBox(“[^"]”)\s*

相关问题