[英]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.