【发布时间】:2009-11-12 16:18:46
【问题描述】:
我的文本格式为:
Name=Value1
Name=Value2
Name=Value3
使用 Perl,我想匹配 /Name=(.+?)/ 每次出现并提取 (.+?) 并将其推送到数组中。我知道我可以使用$1 来获取我需要的文本,我可以使用=~ 来执行正则表达式匹配,但我不知道如何获取所有匹配项。
【问题讨论】:
我的文本格式为:
Name=Value1
Name=Value2
Name=Value3
使用 Perl,我想匹配 /Name=(.+?)/ 每次出现并提取 (.+?) 并将其推送到数组中。我知道我可以使用$1 来获取我需要的文本,我可以使用=~ 来执行正则表达式匹配,但我不知道如何获取所有匹配项。
【问题讨论】:
列表上下文中的m//g 返回所有捕获的匹配项。
#!/usr/bin/perl
use strict; use warnings;
my $str = <<EO_STR;
Name=Value1
Name=Value2
Name=Value3
EO_STR
my @matches = $str =~ /=(\w+)/g;
# or my @matches = $str =~ /=([^\n]+)/g;
# or my @matches = $str =~ /=(.+)$/mg;
# depending on what you want to capture
print "@matches\n";
但是,您似乎正在解析 INI 样式的配置文件。在这种情况下,我会推荐Config::Std。
【讨论】:
g。
my @values;
while(<DATA>){
chomp;
push @values, /Name=(.+?)$/;
}
print join " " => @values,"\n";
__DATA__
Name=Value1
Name=Value2
Name=Value3
【讨论】:
/Name=(.+?)$/ and push @values, $1。甚至只是my @values = map /Name=(.+?)$/, <DATA>;
下面将把所有匹配的正则表达式放在一个数组中。
push (@matches,$&) while($string =~ /=(.+)$/g );
【讨论】:
使用Config:: 模块读取配置数据。对于这样简单的事情,我可能会联系ConfigReader::Simple。尽可能远离杂草真是太好了。
【讨论】:
您可能更喜欢尝试语法引擎,而不是使用正则表达式:
我之前在 SO 上给出了Parse::ResDescent 答案的 sn-p。但是 Regexp::Grammars 看起来很有趣,并且受到Perl6 rules & grammars 的影响。
所以我想我会对 Regexp::Grammars 有所了解;-)
use strict;
use warnings;
use 5.010;
my $text = q{
Name=Value1
Name = Value2
Name=Value3
};
my $grammar = do {
use Regexp::Grammars;
qr{
<[VariableDeclare]>*
<rule: VariableDeclare>
<Var> \= <Value>
<token: Var> Name
<rule: Value> <MATCH= ([\w]+) >
}xms;
};
if ( $text =~ $grammar ) {
my @Name_values = map { $_->{Value} } @{ $/{VariableDeclare} };
say "@Name_values";
}
以上代码输出Value1 Value2 Value3。
非常好!唯一需要注意的是,它需要 Perl 5.10,而且对于您提供的示例来说,它可能有点矫枉过正;-)
/I3az/
【讨论】: