Perl的新手,我尝试使用REGEXP从文件行获取参数。
对应的行可以采用几种形式:
(ATT: X:0.0 Y:0.0)
(ATT: X:0 Y:2.70823)
(bch x1.00003 y0.99988)
目标是检索X和Y值。
我写了这个
(($x, $xd, $y, $yd) = ($v =~ m/[xX][^0-9+-]*([+-]?\d+(\.\d+)?)[^0-9+-yY]*[yY][^0-9+-]*([+-]?\d+(\.\d+)?)/ ))
它可以工作,但是我必须使用4个变量来实现
有更好的方法吗?
此外,如果我们现在考虑可以在行中反转X和Y值,例如
(ATT: Y:0.0 X:0.0)
我的解决方案不再起作用...是否有一种在所有情况下都可以使用的解决方案?
谢谢您的帮助
答案 0 :(得分:1)
也许是这样吗?
#!/usr/bin/perl
use strict;
use warnings;
# NOTE: change this if you need it to be more strict, e.g. should not match "0"
my $regex_float = qr/\d+(?:\.\d+)?/;
# match: white space + one letter (group 1) +
# (optional) : + floating number (group 2)
my $regex_variable = qr/\s+(\w):?(${regex_float})/;
while (<DATA>) {
chomp;
# applied multiple times
# returns list: g1, g2, g1, g2, ...
my %values =
map { uc } # upper case variable name
($_ =~ /${regex_variable}/g);
my $x = $values{X} // die "can't find X on line '$_'\n";
my $y = $values{Y} // die "can't find Y on line '$_'\n";
print "$_ -> (${x}, ${y})\n";
}
exit 0;
__DATA__
(ATT: X:0.0 Y:0.0)
(ATT: X:0 Y:2.70823)
(bch x1.00003 y0.99988)
(ATT: Y:3.0 X:4.0)
Time-space continuum with lazy and x: nast y: generator t:1.0 Y2.1 z3.2 x:4.3
测试输出:
$ perl dummy.pl
(ATT: X:0.0 Y:0.0) -> (0.0, 0.0)
(ATT: X:0 Y:2.70823) -> (0, 2.70823)
(bch x1.00003 y0.99988) -> (1.00003, 0.99988)
(ATT: Y:3.0 X:4.0) -> (4.0, 3.0)
Time-space continuum with lazy and x: nast y: generator t:1.0 Y2.1 z3.2 x:4.3 -> (4.3, 2.1)
注意:取自此SO question
的float正则表达式答案 1 :(得分:1)
这可以解决问题(切换注释以测试每个注释):
$ cat file.pl
use strict;
#my $str = '(ATT: X:0.0 Y:0.0)';
#my $str = '(ATT: X:0 Y:2.70823)';
#my $str = '(bch x1.00003 y0.99988)';
my $str = '(bch y1.00003 x0.99988)';
my %hash;
if ( $str =~ /([xy]):*([\d.]+)\s+([xy]):*([\d.]+)/i ) {
$hash{lc($1)} = $2;
$hash{lc($3)} = $4;
print "X = ". $hash{'x'} . "\n";
print "Y = ". $hash{'y'} . "\n";
}
$ perl file.pl
X = 0.99988
Y = 1.00003