再帰的パーサー呼び出しに基づくアルゴリズム。いくつかのモードがあります: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
あなたが入力し、期待される出力と例を追加することができます。
ここでは、コードのですか? –
一般に、これは正規表現では実行できません。いくつかの種類のSQLパーサーを使用する必要があります。同様の質問:http://stackoverflow.com/questions/9842991/regex-to-remove-single-line-sql-comments。 –
私はむしろVBA通常の文字列処理関数をこのタスクに使用したいと思っています。 – dnep