2017-02-16 57 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解决方案来匹配两个文本文件之间的差异)。 –