Perl REGEXP用于浮动

时间:2019-02-07 16:24:56

标签: regex perl

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)

我的解决方案不再起作用...是否有一种在所有情况下都可以使用的解决方案?

谢谢您的帮助

2 个答案:

答案 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