2016-03-21 5 views
0

Teradata SQLテキストファイルからコメントを削除するVBA Regexを作成しようとしています。Teradata SQLテキストファイルからコメントを削除するVBA Regex

コメントの2種類があります

1から 2つのダッシュの発生、「 - 」コメントとしてライン の残りを表すが。

2./* xxx */ '/ *'と '* /'の間のすべてはコメントです。このタイプのコメント は、1行以上に広がっている可能性があります。

合併症は、として単一引用符で囲まれたテキストである「--theseダッシュので今後のコメントが意味するものではなく、単一引用符である」を。

私はRegexに新しく、これを理解しようとすると、私を超えていることが証明されています。私は否定的な先読みのラインに沿って考えてきました。

誰でも助けてください。

これは私の知る限りが持っているようです。

タイプ1:

\ - \ - [\ S \ T] * $

タイプ2:

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

+1

あなたが入力し、期待される出力と例を追加することができます。

ここでは、コードのですか? –

+0

一般に、これは正規表現では実行できません。いくつかの種類のSQLパーサーを使用する必要があります。同様の質問:http://stackoverflow.com/questions/9842991/regex-to-remove-single-line-sql-comments。 –

+0

私はむしろVBA通常の文字列処理関数をこのタスクに使用したいと思っています。 – dnep

答えて

0

再帰的パーサー呼び出しに基づくアルゴリズム。いくつかのモードがあります: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 
+0

ありがとうございます。コメントが行の最初の文字でない場合以外はうまく動作します。その状況に対応するための簡単な変更はありますか? – John

+0

@Johnはコードをチェックし、パターンを修正しました。 – omegastripes

+0

もう一度お手伝いをしていただき、ありがとうございます。私が今試したほとんどの場合完全に動作します。例外は次のとおりです...この が コメントです/ * ---うるさく、これは「また、この */ – John

関連する問題