2013-09-12 3 views
1

Im пытается проанализировать файл, в котором каждая строка имеет 3 поплавки (1, +1.0 -1.0 - допустимые значения), а в то время как регулярное выражение в фрагменте соответствует значению float, я не знаю, как я должен использовать квантор Perl {n} для сопоставления нескольких поплавков в одной строке.Perl regular expression {} quantifier multiple matches

#!/usr/bin/perl 
use strict; 
use warnings; 

open(my $fh, "<", "floatNumbers.txt") or die "Cannot open < floatNumbers.txt"; 

while(<$fh>) 
{ 
    if ($_=~m/([-+]?\d*[\.[0-9]*]?\s*)/) 
    { 
    print $1."\n"; 
    } 
} 

Фрагмент кода, я попытался сопоставить 3 поплавки внутри линии. Могут ли читатели помочь мне с правильным использованием кванта {}?

if ($_=~m/([-+]?\d*[\.[0-9]*]?\s*){3}/) 
+0

Некоторые вопросы. Имеет ли каждая строка только 3 значения? Разделяются ли они метриками? Что определить как поплавок? Покажите несколько полных образцов. – sln

ответ

3

Вы пытаетесь сделать извлечение и проверку одновременно. Я бы с:

sub is_float { 
    return $_[0] =~/
    ^
     [-+]? 
     (?: \d+(?:\.[0-9]*)? # 9, 9., 9.9 
     |   \.[0-9]+ # .9 
    ) 
     \z 
    /x; 
} 

while (<$fh>) { 
    my @fields = split; 

    if (@fields != 3 || grep { !is_float($_) } @fields) { 
     warn("Syntax error at line $.\n"); 
     next; 
    } 

    print("@fields\n"); 
} 

Обратите внимание, что ваша проверка consdered ., [ и ...0...0... быть числами. Я это исправил.

1

Quntifiers позволяет указать, сколько раз вы хотите что-то сопоставить в регулярном выражении.

Например /(ba){3}/ будет соответствовать ba в строке точно 3 раза:

bababanfnfd = bababa, но не

Бабой = нет соответствия.

Вы можете также использовать (взято из: http://perldoc.perl.org/perlrequick.html):

  • стоит? = Матч «» 1 или 0 раз
  • а * = матч «а» 0 или более раз, то есть, любое число раз
  • а + = матч «» 1 или более раз, то есть, по крайней мере, один раз
  • a {n, m} = совпадение не менее n раз, но не более m раз.
  • а {п} = совпадение по крайней мере, п или более раз
  • а {п} = матч ровно п раз
1

Это обобщенный шаблон, который я думаю, что делает то, что вы говорите:

# ^\s*(?:[-+]?(?=[^\s\d]*\d)\d*\.?\d*(?:\s+|$)){3}$ 

^       # BOL 
\s*      # optional whitespaces 
(?:      # Grouping start 
     [-+]?      # optional -+ 
     (?= [^\s\d]* \d)   # lookahead for \d 
     \d* \.? \d*    # match this form (everything optional but guaranteed a \d) 
     (?: \s+ | $)    # whitespaces or EOL 
){3}      # Grouping end, do 3 times 
$       # EOL