0

次のようなログファイルがあります。

some strings...
<FX>
another strings...
<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>
some strings...
<FX>
<FX>
 <TEG1>
 </TEG1>
</FX>

私はそれを解析して、この結果を得る必要があります:

<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>

<FX>
 <TEG3>
 </TEG3>
</FX>

私はすでに次のような正規表現を書いています:

<FX>([\s\S]+?)</FX>

しかし、これは次の一致を返します:

<FX>
another strings...
<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>

<FX>
<FX>
 <TEG1>
 </TEG1>
</FX>

誰でも正規表現を手伝ってもらえますか? ありがとうございます。

4

2 に答える 2

0

「別の文字列」の背後に何が隠れているかに応じて、次のことを回避できます。

  Dim sAll : sAll = goFS.OpenTextFile("..\data\15168620.txt").ReadAll()
  WScript.Echo sAll
  WScript.Echo "--------"
  Dim reX  : Set reX = New RegExp
  reX.Global  = True
  reX.Pattern = "<FX>[\s\S]*?(<FX>[\s\S]+?</FX>)"
  Dim oMTS : Set oMTS = reX.Execute(sAll)
  Dim oMT
  For Each oMT in oMTS
      WScript.Echo oMT.SubMatches(0)
      WScript.Echo "--------"
  Next

出力:

some strings...
<FX>
another strings...
<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>
some strings...
<FX>
<FX>
 <TEG1>
 </TEG1>
</FX>

--------
<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>
--------
<FX>
 <TEG1>
 </TEG1>
</FX>
--------

アップデート:

歩行者のアプローチを回避できることを願っています。

  Dim sAll : sAll = goFS.OpenTextFile("..\data\15168620-2.txt").ReadAll()
  WScript.Echo sAll
  WScript.Echo "--------"
  Dim aAll : aAll = Split(sAll, "FX>")
  Dim sTry
  For Each sTry In aAll
      If "</" = Right(sTry, 2) Then
         WScript.Echo "<FX>" & sTry & "FX>"
         WScript.Echo "--------"
      End If
  Next

出力:

some strings...
<FX>
another <FX> strings...
<FX><FX><FX><FX><FX>
<FX>
<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>
some strings...
<FX>
<FX>
 <TEG1>
 </TEG1>
</FX>

--------
<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>
--------
<FX>
 <TEG1>
 </TEG1>
</FX>
--------

更新 II:

歩行者のアプローチ - 行ごとに読み取り、 <FX>で新しいコレクションを開始し、 でコレクション/出力を処理します</FX>

  Dim alLines : Set alLines = CreateObject("System.Collections.ArrayList")
  alLines.Capacity = 500
  Dim oTS     : Set oTS     = goFS.OpenTextFile("..\data\15168620-2.txt")
  Do Until oTS.AtEndOfStream
     Dim sLine : sLine = oTS.Readline()
     Select Case True
       Case "<FX>" = Left(sLine, 4)
            alLines.Clear
            alLines.Add sLine
       Case "</FX>" = Left(sLine, 5)
            alLines.Add sLine
            WScript.Echo Join(alLines.ToArray(), vbCrLf)
            WScript.Echo "--------"
       Case Else
            alLines.Add sLine
     End Select
  Loop
  oTS.Close

出力:

<FX>
 <TEG1>
  <TEG2>
  </TEG2>
 </TEG1>
</FX>
--------
<FX>
 <TEG1>
 </TEG1>
</FX>
--------
于 2013-03-02T15:13:11.067 に答える
0

とても巨大なファイル (10 GB) では、RegExp価値がありません。これが私の考えです。

' StripInvalidXML.vbs
Option Explicit

Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Const TAG_OPEN = "<FX>", TAG_CLOSE = "</FX>"

Dim fso, fin, fout
Dim sLine, sBlock

Set fso  = CreateObject("Scripting.FileSystemObject")
Set fin  = fso.OpenTextFile("input_log.xml",  ForReading,  False)
Set fout = fso.OpenTextFile("output_log.xml", ForAppending, True)

Do Until fin.AtEndOfStream
    sLine = fin.ReadLine
    If sLine = TAG_OPEN Then
        sBlock = sLine
    Else
        sBlock = sBlock & sLine
    End If
    sBlock = sBlock & vbNewLine
    If sLine = TAG_CLOSE Then
        fout.WriteLine sBlock
    End If
Loop

fin.Close
fout.Close
于 2013-03-03T13:27:32.033 に答える