我试图检测并更改以下格式的列表。输入字符串
bla bla
* a
* list
* here
bla * bla
bl**a
* another
* list
期望的输出:
bla bla
LIST
+ a
+ list
+ here
END
bla * bla
bl**a
LIST
+ another
+ list
END
在此基础上,我意识到我应该使用另一种解析器,并且正则表达式不是这项工作的最佳工具。尽管如此,它让我很好奇,我想知道这个问题是否可以用正则表达式解决。我可以检测到列表并添加LIST / END标记:
s/((^\* .*\n){2,})/LIST\n\1\nEND/gm;
但是,我如何结束更改列表中的各个项目?有没有办法使用这些量化的捕获组?使用s/^\* /+ /g
进行另一次传递是不可能的,因为我只对两个或更多项的列表感兴趣。
答案 0 :(得分:8)
使用Perl正则表达式(正则表达式)确实可以解决这个问题
嵌套的packake_id old_dat old_location_id new_date new_location_id
PACK001 2018-04-03 123 2018-04-04 436
可以解决问题:
s///
$/=undef;
$_=<DATA>;
s{((^\* .*\n){2,})}{
"LIST\n$1END\n"=~s{^\*}{+}mgr;
}gme;
print ;
__DATA__
bla bla
* a
* list
* here
bla * bla
bl**a
* another
* list
答案 1 :(得分:1)
最简单的方法是将数据读入哈希值,然后在附加任何新格式的情况下再次写出数据:
#!perl
use strict;
use warnings;
use feature qw(say);
my %structured_list;
my @keys;
my $key;
# read data in storing lists under associated keys as array references
while (my $line = readline(*DATA)) {
chomp $line;
if ($line =~ /^\*/) {
# this could be simplified
push @{$structured_list{$key}}, $line =~ s/^\*\s*//gr;
}
else {
$key = $line;
push @keys, $key;
$structured_list{$key} = [];
}
}
# read keys back out in order
foreach my $list_key (@keys) {
if (@{$structured_list{$list_key}}) {
say $list_key;
say "LIST";
foreach my $val (@{$structured_list{$list_key}}) {
say "+ $val";
}
say "END";
}
else {
say $list_key;
}
}
__DATA__
bla bla
* a
* list
* here
bla * bla
bl**a
* another
* list
输出:
➜ perl test.pl
bla bla
LIST
+ a
+ list
+ here
END
bla * bla
bl**a
LIST
+ another
+ list
END