2017-02-16 55 views
1

我正嘗試使用RegEx從多行字符串中獲取數據塊。VBScript正則表達式 - 查找模式之間的數據塊

要搜索的字符串

 
***** a.txt 
17=xxx 
570=N 
55=yyy 
***** b.TXT 
17=XXX 
570=Y 
55=yyy 
***** 

***** a.txt 
38=10500.000000 
711=1 
311=0000000006630265 
***** b.TXT 
38=10500.000000 
311=0000000006630265 
***** 

我需要 - 東西之間*****阻止

 
17=xxx 
570=N 
55=yyy 

17=XXX 
570=Y 
55=yyy 

38=10500.000000 
711=1 
311=0000000006630265 

38=10500.000000 
311=0000000006630265 

到目前爲止我的代碼

 
Set objRegEx = CreateObject("VBScript.RegExp") 
objRegEx.Global = True 
objRegEx.MultiLine = True 
objRegEx.IgnoreCase = True 
objRegEx.Pattern = "\*\*\*\*\*(?:.|\n|\r)*?\*\*\*\*\*" 
Set strMatches = objRegEx.Execute(objExec.StdOut.ReadAll()) 
If strMatches.Count > 0 Then 
    For Each strMatch In strMatches 
     Wscript.Echo strMatch 
    Next 
End If 
Set objRegEx = Nothing 

回答

3

你需要將最後的*匹配你的消費模式的一部分變成積極的前瞻。此外,強烈建議擺脫(.|\r|\n)*?,因爲它會減慢匹配過程,請改爲使用[\s\S]*?

使用

\*{5}(?!\s*\*{5}).*[\r\n]+([\s\S]*?)(?=\*{5}) 

Submatches搶到的第一個項目。用.*[\r\n]+,我建議跳過*****起始行的其餘部分。

詳細

  • \*{5} - 5星號
  • (?!\s*\*{5}) - 如果有0+空格,接着用5個星號
  • 失敗的比賽
  • .*[\r\n]+ - 匹配換行符行的其餘部分
  • ([\s\S]*?) - 捕獲組1(其值存儲在Match對象的Submatches屬性中)匹配任何0+ cha rs儘可能少到第一個....
  • (?=\*{5}) - 位置跟着5個星號不被消耗,只是他們的存在被檢查。

regex demo

如果您展開正則表達式,它看起來醜陋,但它是更有效:

\*{5}(?!\s*\*{5}).*[\r\n]+([^*]*(?:\*(?!\*{4})[^*]*)*) 

another regex demo

VBS代碼:

Set objRegEx = CreateObject("VBScript.RegExp") 
objRegEx.Global = True 
objRegEx.Pattern = "\*{5}(?!\s*\*{5}).*[\r\n]+([^*]*(?:\*(?!\*{4})[^*]*)*)" 
Set strMatches = objRegEx.Execute(objExec.StdOut.ReadAll()) 
If strMatches.Count > 0 Then 
    For Each strMatch In strMatches 
     Wscript.Echo strMatch.Submatches(0) 
    Next 
End If 
Set objRegEx = Nothing 
+0

謝謝Wiktor。幾個問題與這個模式 - 1)標題也提取(例如***** a.txt)。我不需要那個。 2)它也匹配*****&***** a.txt之間的空行。 –

+0

好吧,2)是真實的,但它很容易處理與前瞻(見我更新的答案)。至於1),我說你必須訪問'strMatch.Submatches(0)'中的第一項。注意你不需要設置'objRegEx.MultiLine = True'。 –

+0

當我使用第二個正則表達式時,我在最後得到了*****,當我使用第一個正則表達式時,我得不到它。 –

2

只需捕獲連續編號行

Option Explicit 

Dim data 
    With WScript.CreateObject("WScript.Shell") 
     data = .Exec("fc.exe /n 1.txt 2.txt").StdOut.ReadAll() 
    End With 

Dim match 
    With New RegExp 
     .Pattern = "(?:^[ ]*[0-9].*?$[\r\n]+)+" 
     .Global = True 
     .MultiLine = True 
     For Each match in .Execute(data) 
      WScript.StdOut.WriteLine "---------------------------------------" 
      WScript.StdOut.WriteLine match.Value 
     Next 
    End With 
+0

您的解決方案也可以很好地工作。 –

+1

只有沒有不以數字開頭的行,並且如果行以數字開頭,還會匹配第一個「*****」之前的任何文本,它才起作用。它不檢查數據是否在星號之間。 –

+0

我的場景中永遠不會有數字開頭的行。而且我也正在解析通過'fc'獲得的信息(構建一個vbs解決方案來匹配兩個文本文件之間的差異)。 –