簡體   English   中英

捕獲Perl文件中某些行之間的選擇數據。

[英]Capturing select data between certain lines in a file in Perl.

我有一個包含這種內容的文件:

*** X REGION ***
|-------------------------------------------------------------------------------------------------|
| X                                                                                               |                                                                                           
| addr              tag          extra data   |
|-------------------------------------------------------------------------------------------------|
| $A1    label_A1X                   |       1 |
| $A2    label_A2X                   |       2 |
| $A3    label_A3X                   |       3 |

*** Y REGION ***

|-------------------------------------------------------------------------------------------------|
| Y                                                                                            |
| addr              tag           extra data  |
|-------------------------------------------------------------------------------------------------|
| $0     label_0Y                    |        99 |
| $1                                 |        98 |

我需要在'addr'和'tag'下捕獲數據; 被逗號隔開; 分別為'X REGION'和'Y REGION'下的記錄。 這是我試過的:

open($fh1, "<", $memFile) or warn "Cannot open $memFile, $!";            #input file with contents as described above. 

open($fh, "+<", $XFile) or warn "Cannot open $XFile, $!";                
open($fh2, "+<", $YFile) or warn "Cannot open $YFile, $!";               

while(my $line = <$fh1>)
{

  chomp $line;
  $line = $line if (/\s+\*\*\*\s+X REGION\s+\*\*\*/ .. /\s+\*\*\*\s+Y REGION\s+\*\*\*/);        #Trying to get at the stuff in the X region.
  if($line =~ /\s+|\s+\$(.*)\s+(.*)\s+|(.*)/) 
  {
    $line = "$1,$2";
    print $fh $line; 
    print $fh "\n";
  }

  my $lastLineNum = `tail -1 filename`;
  $line = $line if (/\*\*\* Y REGION \*\*\*/ .. $lastLineNum);                      #Trying to get at the stuff in the Y region.
  if($line =~ /\s+|\s+\$(.*)\s+(.*)\s+|(.*)/)
  {
    $line = "$1,$2";
    print $fh2 $line;
    print $fh2 "\n";
  }

}

這表示$ 1和$ 2未初始化。 正則表達式是不正確的? 還有(還有)還有什么?

這是一段代碼,可以根據需要運行(充分利用默認的perl隱式var $_ ):

# use die instead of warn, don't go ahead if there is no file
open(my $fin, "<", $memFile) or die "Cannot open $memFile, $!"; 

while(<$fin>)
{
    # Flip flop between X and Y regions
    if (/[*]{3}\h+X REGION\h+[*]{3}/../[*]{3}\h+Y REGION\h+[*]{3}/) {
        print "X: $1,$2\n" if (/.*\$(\S*)\h*(\S*)\h*[|]/)
    }

    # Flip flop from Y till the end, using undef no need of external tail
    if (/[*]{3}\h+Y REGION\h+[*]{3}/..undef) {
        print "Y: $1,$2\n" if (/.*\$(\S*)\h*(\S*)\h*[|]/)
    }
}

這是輸出:

X: A1,label_A1X
X: A2,label_A2X
X: A3,label_A3X
Y: 0,label_0Y
Y: 1,

在線運行演示

談論你的代碼有很多要解決的問題:

  • 在您的正則表達式來選擇分隔符管道之間的元素| 需要轉義:使用反斜杠\\| 或者char類[|] (我更喜歡后者)

  • \\s匹配也換行(嚴格\\n或回車\\r \\n ),不要將它用作一般空格加tab \\t替換。 請改用\\h (僅限水平空格)

  • 你用\\s+啟動正則表達式,但在示例中,表行的第一個字符始終是'|'

  • .*匹配除換行符之外的任何東西(包括空格)( \\n\\r

  • 所以像.*\\s+這樣的正則表達式匹配整行和新行( \\s )以及下一行中的可能空格

  • 觸發器perl運算符..為您提供所選區域(包括邊緣)中的行,每次都是一行 ,所以也是正則表達式的轉義管道形式:

    \\s+[|]\\s+\\$(.*)\\s+(.*)\\s+[|](.*)

    根本不能匹配看到它在文本上的行為

所以我已經用這個替換了數據提取正則表達式:

.*\$(\S*)\h*(\S*)\h*[|]

正則表達式突圍

.*\$     # matches all till a literal dollar '$'
(\S*)    # Capturing group $1, matches zero or more non-space char [^\s]
         # can be replaced with (\w*) if your labels matches [0-9a-zA-Z_]
\h*      # Match zero or more horizontal spaces 
(\S*)    # Capturing group $2, as above
\h*      # Match zero or more horizontal spaces 
[|]      # Match a literal pipe '|'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM