我有一个带有分层文本的结构化文件,用于描述Delphi中的GUI(DFM文件)。
假设我有这个文件,我必须匹配所有“Color = xxx”行,它们在TmyButton(标记)的上下文中,但不在其他上下文中。在TMyButton-Context中,不会有更深层次的层次。
object frmMain: TfrmMain
Left = 311
Top = 201
Color = clBtnFace
object MyFirstButton: TMyButton
Left = 555
Top = 301
Color = 16645072 <<<<<<MATCH THIS
OnClick = ButtonClick
end
object MyLabel: TLabel
Left = 362
Top = 224
Caption = 'a Caption'
Color = 16772831
Font.Color = clWindowText
end
object Panel2: TLTPanel
Left = 348
Top = 58
Width = 444
Height = 155
Color = clRed
object MyOtherButton: TMyButton
Left = 555
Top = 301
Color = 16645072 <<<<<<MATCH THIS
OnClick = ButtonClick
end
end
end
我尝试了两天,经历了许多不同的尝试。 这里有一些我不完整的模式:
/^[ ]{2,}object [A-Za-z0-9]+: TmyButton\r\n/mi <<<Matches the needed context
/^[ ]{4,}Color = [A-Za-z0-9]+\r\n/mi <<<Matches the needed result
/^[ ]{2,}end\r\n/mi <<<Matches the end of the context
(我不知道为什么,但我不得不使用“\ r \ n”而不是“$”......)。我需要将它们放在一起,但忽略除了其他“对象xxx:yyy”和“end”行之外的其他行....
我很乐意得到一些帮助!
答案 0 :(得分:1)
如果我理解正确,您会尝试为此创建单个正则表达式。没有理由这样做。
object [A-Za-z0-9]+: TmyButton
Color = [A-Za-z0-9]+
的每一行,直到找到它或到达end
关键字。 如果您尝试修改大量源文件,可以使用一些脚本来实现此目的。
答案 1 :(得分:1)
在复杂上下文中匹配一行需要一个名为lookaround的正则表达式功能,如果您想要或必须使用单个正则表达式执行此操作。具体来说,您需要PCRE不提供的可变长度后视镜。
所以有两种可能性: 使用像Rorick建议的脚本方法或使用匹配从所需上下文开始到实际匹配的所有内容的正则表达式,并使用捕获组提取它。这可以用
完成[ ]{2,}object \w+: TMyButton\r\n.*?^([ ]{4,}Color = \w+[ \t]*\r\n)
(为清晰起见,插入空间周围的括号)。您的匹配将在捕获组\1
嵌套结构通常不适合正则表达式(更适合解析器),但如果您确定所提到的数据结构,它可能正常工作。
答案 2 :(得分:1)
我知道这不是PCRE,而是软件考古学的一个很好的替代方案。
如果从命令提示符执行此操作,您可以随时使用AWK。该脚本如下所示:
BEGIN { inObj = 0; } // Not really necessary
/TMyButton/ { inObj = 1; }
/end$/ { inObj = 0; }
/^[ ]{4,}Color = [A-Za-z0-9]+\r\n/ && inObj == 1
{ //do whatever you need to do
print $3;
}
AWK可以在互联网上找到。我会尝试GAWK。