1

Let's say I have the following string

my $val = "3.4 -22.352 4.0"

The goal is to extract each decimal number by itself. There can be any number of spaces on each side or in between. It is also important to make sure that there is exactly 3 numbers present, and no other junk. I have something like this, but it doesn't work:

my @parts = ($val =~ /((\s*[-+]?\d{1,3}\.\d{1,3}\s*)){3}/)

if (scalar(@parts) == 3) {
    print "Validated!\n";

    for my $i (@parts) {
        print "$i\n";
    }
}

For some reason I get the last one twice.

4

6 に答える 6

1

正規表現と戦う代わりに、 and を使用splitlooks_like_numberます。

use warnings;
use strict;
use Scalar::Util qw(looks_like_number);

my $val = "3.4 -22.352 4.0";
my @parts = split /\s+/, $val;
if (scalar(@parts) == 3) {
    my $ok = 0;
    for (@parts) {
        $ok++ if looks_like_number($_);
    }
    if ($ok == 3) {
        print "Validated!\n";
        for my $i (@parts) {
            print "$i\n";
        }
    }    
}
于 2013-05-15T18:29:22.017 に答える
1

量指定子を適用しても、各キャプチャ グループは 1 つの値のみを取得します。3 つの値が必要な場合は、キャプチャ グループを 3 回繰り返す必要があります。例えば:

my $num = qr/[-+]?\d{1,3}\.\d{1,3}/;
my @nums = $val =~ /^\s*($num)\s+($num)\s+($num)\s*$/;

if(@nums){
    print "Valid, and no need to check the number of elements.\n";
}
于 2013-05-15T18:29:30.503 に答える
1

かっこのセットが 2 つあるため、2 つの値が返されます。どちらのセットも正規表現の同じ部分を囲んでいるため、両方の値は同じになります。


検証と抽出は、必ずしも同時に実行できるとは限りません。

最初に抽出するという 2 つのステップで行うのは非常に簡単です。

my @nums = split ' ', $val;
die "Invalid\n" if @parts != 3;
for (@nums) {
   die "Invalid\n" if !/^[-+]?[0-9]{1,3}\.[0-9]{1,3}\z/;
}

1 つのステップで実行できますが、冗長性が伴います。

my $num_pat = qr/[-+]?[0-9]{1,3}\.[0-9]{1,3}/;
my @nums = $val =~ /^($num_pat)\s+($num_pat)\s+($num_pat)\z/
   or die "Invalid\n";
于 2013-05-15T18:29:33.520 に答える
1
my $val = "3.4 -22.352 4.0";
my $length = $val =~ s/((^|\s)\S)/$1/g;
#determines the number of tokens

if ($length == 3)
{
     while($val=~/([-+]?[0-9]{1,3}\.[0-9]{1,3})/g)
     {
         print "$1\n";
     }
}

を使用/gすると、文字列をループして、制限に適合する値を (一度に 1 つずつ) 抽出できます。パターンに一致するすべての「トークン」が繰り返されるまで、これが行われます。簡潔で、補助配列を作成する必要がないため、このソリューションが気に入っています。また、正規表現で 3 つの抽出を使用するよりも一般的な回答です。

于 2013-05-15T18:53:25.780 に答える
1

ここにはいくつかの問題があります。

1) 3 つの数字のみが必要な場合は、正規表現で行の開始 (^) と終了 ($) を固定する必要があります。

2) 括弧が 2 組あるのはなぜですか? 書かれているように、2番目のペアは冗長です。

3) 正規表現がある場合、返される値の数は通常、左括弧で数えられます (?: またはその他の修飾子を使用しない限り)。この例では 2 つあるため、2 つの値のみが返されます。括弧が冗長なため、同じ値がそれぞれ 2 回得られます。

于 2013-05-15T18:33:40.520 に答える