我想使用Perl循环遍历文件(或数组),在匹配正则表达式时启动处理元素,并在满足另一个正则表达式时停止处理。
一种方法是将一个变量用作标志(满足启动正则表达式时= 1,满足结束正则表达式时= 0)。
例如,以下作品但非常难看!!
use strict;
my @file = (
"<title>List of widgets</title>\n",
"<widgets>\n",
" <button>widget001.xml</button>\n",
" <textArea>widget002.xml</textArea>\n",
" <menu>widget002.xml</menu>\n",
"</widgets>\n",
"<footer>\n",
" This is the footer\n",
"</footer>\n",
);
my $in_list_widgets = 0;
for my $line (@file) {
if ($line=~m%<widgets%) {
$in_list_widgets = 1;
} elsif ($line=~m%</widgets>%) {
$in_list_widgets = 0;
} else {
if ($in_list_widgets == 1) {
&process_line($line);
} else {
#Do nothing
}
}
}
sub process_line {
my $line = shift;
print $line;
}
什么是更优雅的方式,并仍然得到相同的结果?
<button>widget001.xml</button>
<textArea>widget002.xml</textArea>
<menu>widget002.xml</menu>
由于
答案 0 :(得分:1)
关于这是XML - 它看起来像是 - 我建议使用XML解析器。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> parse ( \*DATA );
$twig -> set_pretty_print('indented');
$_ -> print for map { $twig -> findnodes("//$_",0) } qw ( button textArea menu );
__DATA__
<root>
<title>List of widgets</title>
<widgets>
<button>widget001.xml</button>
<textArea>widget002.xml</textArea>
<menu>widget002.xml</menu>
</widgets>
<footer>
This is the footer
</footer>
</root>
输出:
<button>widget001.xml</button>
<textArea>widget002.xml</textArea>
<menu>widget002.xml</menu>
或者为了清楚起见:
my $twig = XML::Twig -> new -> parsefile('your_file');
foreach my $widgets ( $twig -> root -> children('widgets') ) {
foreach my $child ( $widgets -> children ) {
$child -> print;
print "\n";
}
}
答案 1 :(得分:0)
您可以使用如下语法<match_regex_1> .. <match_regex_2>
:
use strict;
my @file = (
"<title>List of widgets</title>\n",
"<widgets>\n",
" <button>widget001.xml</button>\n",
" <textArea>widget002.xml</textArea>\n",
" <menu>widget002.xml</menu>\n",
"</widgets>\n",
"<footer>\n",
" This is the footer\n",
"</footer>\n",
);
my $in_list_widgets = 0;
for my $line (@file) {
if ($line=~m%<widgets% .. $line=~m%</widgets>%) {
&process_line($line) if ($line!~m%<(widgets|/widgets>)%);
} else {
#Do nothing
}
}
sub process_line {
my $line = shift;
print $line;
}
一些解释:
if ($line=~m%<widgets% .. $line=~m%</widgets>%)
:当第一个条件为真时开始执行以下块,直到最后一个条件为真。&process_line($line) if ($line!~m%<(widgets|/widgets>)%);
:如果没有if ($line!~m%...
,行<widgets>
和</widgets>
也会被处理希望它可以提供帮助。