2013-03-01 2 views
0

У меня есть файл журнала, как это:регулярное выражение на VBScript

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> 

Может кто-нибудь помочь мне с регулярным выражением? Спасибо в совет.

+0

Для этого вы можете попробовать использовать синтаксический анализатор XML вместо Regex. В VBScript вы можете использовать 'msxml', например. – MaxiWheat

+0

@MaxiWheat - размер (10 ГБ) и тот факт, что данные искажены, делают использование msxml невозможным. –

ответ

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> 
-------- 

Update:

Я все еще надеюсь, что мы может избежать пешеходного подхода:

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> 
-------- 
+0

Благодарим вас за ответ. Вы задали хороший вопрос: «В зависимости от того, что скрывается за вашими« другими строками »». Иногда мои «другие строки» могут содержать много открытых тегов , иногда он может содержать простой текст, например «errors in db ...». Может быть, алгоритм должен выглядеть следующим образом: в строке строк найдите «последний» тег и получите всю информацию между и тегами. Но как он пишет по регулярному выражению - я не знаю ... – Iurii

+0

@lurii - см. Обновление. –

+0

Благодарим вас за помощь.Я тестировал его на своем примере, и он отлично подходит для меня, но как он будет работать в файле журнала, размер которого равен 10 Гб (поэтому я хочу писать регулярное выражение)? Я проверю его на своей работе в понедельник и расскажу вам о результатах. В противном случае спасибо) – Iurii

0

С таким огромным файлом (10 ГБ) 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 
Смежные вопросы