我想使用正则表达式提取多个文本块。我的正则表达式得到了正确的开始,但也将所有内容返回到文件的末尾。
我正在使用:
re.ignorecase = true
re.multiline = false
re.global = true
re.pattern = "\balias\s=\sX[\s\S]{1,}end"
文件格式的一个例子是:
Metadata Begin
Easting Begin
alias = X
projection = "geodetic"
datum = "GDA94"
Easting End
Northing Begin
alias = Y
projection = "geodetic"
datum = "GDA94"
Northing End
Metadata End
我希望每次出现时从alias
开始提取到下一个End
的文本,这样我就可以一次处理一个别名的详细信息。 e.g。
alias = X
projection = "geodetic"
datum = "GDA94"
Easting End
但是这不会在End
之后获得第一个alias
。相反,[\s\S]
匹配在第一个alias
之后到文件末尾的所有内容。但[\s\S]
是我能想到的唯一一个在每一行结束时越过CrLf的技巧。
是否存在与多行第一个End
匹配的正则表达式?
答案 0 :(得分:3)
你需要一个非贪婪的正则表达式。 [\s\S]{1,}
贪婪,尽可能匹配所有角色。要在找到匹配匹配项后停止此模式,您需要在?
旁边添加非贪婪量词{1,}
。所以它就像[\s\S]{1,}?
。这甚至可以用更简单的形式写成[\s\S]+?
。
re.pattern = "\balias\s=\sX[\s\S]+?end"
如有必要,请在字符\b
之前和之后添加end
。
答案 1 :(得分:1)
我建议采用多步骤方法。
单挑街区:
(Easting|Northing) Begin([\s\S]*?)\1 End
逐行处理其内容
(\S+)\s+=\s+("?)(.*)\2
所以,当放在一起时,我们得到
Option Explicit
Dim reBlock, reLine, input
Dim blockType, blockBody, name, value
Set reBlock = New RegExp
Set reLine = New RegExp
input = LoadYourFile()
reBlock.Pattern = "(Easting|Northing) Begin([\s\S]*?)\1 End"
reBlock.Global = True
reBlock.IgnoreCase = True
reLine.Pattern = "(\S+)\s+=\s+(""?)(.*)\2"
reLine.Global = True
reLine.IgnoreCase = True
For Each block In reBlock.Execute(input)
blockType = block.SubMatches(0)
blockBody = block.SubMatches(1)
For Each line In reLine.Execute(blockBody)
name = line.SubMatches(0)
value = line.SubMatches(2)
WScript.Echo blockType & ": " & name & " = " & value
Next
Next
显着特征