2009-09-24 23 views
1

我有一个结构化的文件,带有描述Delphi(DFM文件)中的GUI的分层文本。正则表达式问题:在上下文匹配

让我们假设我有这个文件,我必须匹配TmyButton(已标记)上下文中的所有“Color = xxx”行,但不匹配其他上下文中的那些行。在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”和“结束”行....

我会很高兴有一些帮助!

回答

1

在复杂环境中匹配一条线需要一个名为lookaround的正则表达式功能,如果您想要或必须用一个正则表达式来完成。具体而言,您需要PCRE不提供的可变长度lookbehind。

所以有两种可能性: 使用像Rorick建议的脚本方法,或者使用正则表达式来匹配从所需上下文开始直到实际匹配的所有内容,并使用捕获组来提取它。这可以通过

[ ]{2,}object \w+: TMyButton\r\n.*?^([ ]{4,}Color = \w+[ \t]*\r\n) 

(为了清楚起见,在插入的空间周围的括号)。然后您的匹配将被捕获组\1

嵌套结构通常不太适合正则表达式(对解析器更好),但如果您确定数据的结构(如您所述),则可能工作正常。

+0

可变长度lookbehind:多数民众赞成我试过的拳头......我想我需要做一些脚本。现在我将首先使用/^[] {2,} object \ w +:TMyButton \ r \ n(^ [] {4,}。+ \ r \ n)+^[] {2,}结束搜索上下文\ r \ n/mi,然后在此匹配中搜索/^[] {4,} Color = \ w + \ r \ n/mi – 2009-09-24 12:45:50

1

如果我正确理解你,你尝试为此创建一个正则表达式。没有理由这样做。

  1. 只要找到符合模式object [A-Za-z0-9]+: TmyButton
  2. 然后检查对每个Color = [A-Za-z0-9]+下一行,直到你找到它,或达到end关键字。直到文件

如果试图修改物料源文件的末尾

  • 重复步骤,你可以使用一些脚本用于这一目的。

  • 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