![](/img/trans.png)
[英]How can I extract a string between matching braces after grep in Perl?
[英]How can I extract a string between matching braces in Perl?
我的輸入文件如下:
HEADER
{ABC|*|DEF {GHI 0 1 0} {{Points {}}}}
{ABC|*|DEF {GHI 0 2 0} {{Points {}}}}
{ABC|*|XYZ:abc:def {GHI 0 22 0} {{Points {{F1 1.1} {F2 1.2} {F3 1.3} {F4 1.4}}}}}
{ABC|*|XYZ:ghi:jkl {JKL 0 372 0} {{Points {}}}}
{ABC|*|XYZ:mno:pqr {GHI 0 34 0} {{Points {}}}}
{
ABC|*|XYZ:abc:pqr {GHI 0 68 0}
{{Points {{F1 11.11} {F2 12.10} {F3 14.11} {F4 16.23}}}}
}
TRAILER
我想將文件解壓縮到如下數組:
$array[0] = "{ABC|*|DEF {GHI 0 1 0} {{Points {}}}}"
$array[1] = "{ABC|*|DEF {GHI 0 2 0} {{Points {}}}}"
$array[2] = "{ABC|*|XYZ:abc:def {GHI 0 22 0} {{Points {{F1 1.1} {F2 1.2} {F3 1.3} {F4 1.4}}}}}"
..
..
$array[5] = "{
ABC|*|XYZ:abc:pqr {GHI 0 68 0}
{{Points {{F1 11.11} {F2 12.10} {F3 14.11} {F4 16.23}}}}
}"
這意味着,我需要將第一個開口花括號與其閉合花括號相匹配,並在其間提取弦。
我已查看以下鏈接,但這不適用於我的問題。 正則表達式在花括號之間獲取字符串“{我想在花括號之間有什么}}”
我正在努力,但如果有人可以幫助我完成他們的專業知識,我會很有幫助
謝謝斯里蘭卡
至少在現代版本的Perl中,這肯定可以用正則表達式完成:
my @array = $str =~ /( \{ (?: [^{}]* | (?0) )* \} )/xg;
print join "\n" => @array;
正則表達式匹配一個大括號塊,它包含非大括號字符或遞歸到自身(匹配嵌套大括號)
編輯:上面的代碼在Perl 5.10+中工作,對於早期版本,遞歸有點冗長:
my $re; $re = qr/ \{ (?: [^{}]* | (??{$re}) )* \} /x;
my @array = $str =~ /$re/xg;
我第二個建議使用Text::Balanced
模塊。 幾行將幫助您前進。
use strict;
use warnings;
use Text::Balanced qw/extract_multiple extract_bracketed/;
my $file;
open my $fileHandle, '<', 'file.txt';
{
local $/ = undef; # or use File::Slurp
$file = <$fileHandle>;
}
close $fileHandle;
my @array = extract_multiple(
$file,
[ sub{extract_bracketed($_[0], '{}')},],
undef,
1
);
print $_,"\n" foreach @array;
{ABC|*|DEF {GHI 0 1 0} {{Points {}}}}
{ABC|*|DEF {GHI 0 2 0} {{Points {}}}}
{ABC|*|XYZ:abc:def {GHI 0 22 0} {{Points {{F1 1.1} {F2 1.2} {F3 1.3} {F4 1.4}}}}}
{ABC|*|XYZ:ghi:jkl {JKL 0 372 0} {{Points {}}}}
{ABC|*|XYZ:mno:pqr {GHI 0 34 0} {{Points {}}}}
{
ABC|*|XYZ:abc:pqr {GHI 0 68 0}
{{Points {{F1 11.11} {F2 12.10} {F3 14.11} {F4 16.23}}}}
}
我不認為純正則表達式是你想要在這里使用的(恕我直言,這可能甚至不能使用正則表達式進行解析)。
相反,構建一個小解析器,類似於此處顯示的: http ://www.perlmonks.org/?node_id = 308039(請參閱dbgunefx(Parson)於2003年11月18日18:29 UTC的回答)
更新似乎它可能是正則表達式 - 我在Mastering正則表達式中看到了匹配嵌套括號的引用(可以在Google Books上找到,因此如果你沒有這本書就可以用Google搜索 - 參見第5章,節“匹配平衡的括號集“)
您可以隨時計算大括號:
my $depth = 0;
my $out = "";
my @list=();
foreach my $fr (split(/([{}])/,$data)) {
$out .= $fr;
if($fr eq '{') {
$depth ++;
}
elsif($fr eq '}') {
$depth --;
if($depth ==0) {
$out =~ s/^.*?({.*}).*$/$1/s; # trim
push @list, $out;
$out = "";
}
}
}
print join("\n==================\n",@list);
這是舊的,簡單的Perl風格(可能很難看)。
對於這種類型的解析,使用狀態機比使用正則表達式要好得多。
正則表達式對於匹配大括號實際上非常糟糕。 根據你想要的深度,你可以為Parse :: RecDescent寫一個完整的語法(比聽起來容易得多!)。 或者,如果您只想獲取塊,請搜索打開“{”標記並關閉“}”,並記住在任何給定時間打開的數量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.