VBA正则表达式从Teradata SQL文本文件中删除注释

时间:2016-03-21 12:13:56

标签: vba regex-lookarounds

我正在尝试编写VBA Regex以从Teradata SQL文本文件中删除注释。

评论有两种类型:

  

1 -   两个破折号的出现,' - '表示该行的剩余部分   作为评论。

     

2。 / * xxx * /   ' / *'之间的一切和' * /'是评论。这种评论   可以分布超过1行。

复杂性是单引号中的文字,例如' - 这些短划线用单引号表示,所以不要表示即将发表的评论

我是Regex的新手,试图弄清楚这一点已经证明超出了我。我一直在思考否定前瞻。

有人可以帮忙吗?

这是我所拥有的:

  

类型1:

     

\ - \ - [\ S \ t] * $

     

类型2:

     

/ \ * [\ S \ S] *?\ * /

1 个答案:

答案 0 :(得分:1)

基于递归解析器调用的算法。有几种模式:3个子类型解析,引用解析和正常的注释。正常模式可以通过任何其他模式交替,这又是唯一的正常模式。因此e。 G。在注释中引用字符,引用文本中的任何注释字符都将被忽略。要搜索的字符取决于当前模式。通过块解析源块,一旦找到目标字符,则分别切换模式,当前块完成,下一个块开始于下一个递归调用。调用堆栈存储瞬态结果。源结束后,向后进程启动,每个被调用的解析器连接并返回它的块,最后检索完整的代码。

以下是代码:

Option Explicit

Sub RemoveComments()

    Dim strOriginal As String
    Dim strProcessed As String

    strOriginal = ReadTextFile("C:\Users\DELL\Desktop\tmp\source.sql", 0) ' -2 - System default, -1 - Unicode, 0 - ASCII
    Parse strOriginal, strProcessed, 0
    WriteTextFile strProcessed, "C:\Users\DELL\Desktop\tmp\result.sql", 0

End Sub

Sub Parse(strSrc As String, strRes As String, lngMode As Long)

    Static objRegExp As Object
    Dim strBeg As String
    Dim objMatches As Object
    Dim lngPos As Long
    Dim lngEscPos As Long
    Dim strRet As String

    If objRegExp Is Nothing Then ' initialize regexp once
        Set objRegExp = CreateObject("VBScript.RegExp")
        With objRegExp
            .Global = False
            .MultiLine = True
            .IgnoreCase = True
        End With
    End If
    strRes = ""
    If strSrc = "" Then Exit Sub ' source completed
    strBeg = "" ' preceding chunk is empty by default
    Select Case lngMode
        Case 0 ' processing normal
            With objRegExp
                .Pattern = "(\/\*)|(^[ \t]*--)|(--)|(\')"
                Set objMatches = .Execute(strSrc)
                If objMatches.Count = 0 Then
                    strRes = strSrc
                    Exit Sub ' source completed
                End If
                lngPos = objMatches(0).FirstIndex
                With objMatches(0)
                    Select Case True
                        Case .SubMatches(0) <> ""
                            lngMode = 1 ' start multiline comment
                        Case .SubMatches(1) <> ""
                            lngMode = 2 ' start whole line comment
                        Case .SubMatches(2) <> ""
                            lngMode = 3 ' start singleline comment
                        Case .SubMatches(3) <> ""
                            lngMode = 4 ' start text in quotes
                            lngPos = lngPos + 1 ' skip found quote char
                    End Select
                End With
            End With
            strBeg = Left(strSrc, lngPos)
            lngPos = lngPos + 1
        Case 1 ' processing multiline comment
            lngMode = 0 ' start normal
            lngPos = InStr(strSrc, "*/")
            If lngPos = 0 Then Exit Sub ' source completed, comment unclosed
            lngPos = lngPos + 2 ' skip comment closing char
        Case 2 ' processing whole line comment
            lngMode = 0 ' start normal
            lngPos = InStr(strSrc, vbCrLf)
            If lngPos = 0 Then Exit Sub ' source completed
            lngPos = lngPos + 2 ' skip new line char
        Case 3 ' processing singleline comment
            lngMode = 0 ' start normal
            lngPos = InStr(strSrc, vbCrLf)
            If lngPos = 0 Then Exit Sub ' source completed
        Case 4 ' processing text within quotes
            lngPos = InStr(strSrc, "'")
            If lngPos = 0 Then Exit Sub ' source completed
            If Mid(strSrc, lngPos, 2) = "''" Then ' escaped quote char ''
                strBeg = Left(strSrc, lngPos + 1) ' store preceding chunk with escaped quote char
                lngPos = lngPos + 2 ' shift next from escaped quote char
            Else
                lngMode = 0 ' start normal
                strBeg = Left(strSrc, lngPos) ' store preceding chunk with quote char
                lngPos = lngPos + 1 ' shift next from quote char
            End If
    End Select
    Parse Mid(strSrc, lngPos), strRet, lngMode ' recursive parser call
    strRes = strBeg & strRet ' concatenate preceding chunk with processed and return result

End Sub