Как проверить число в Perl? - PullRequest
2 голосов
/ 11 мая 2011

Я знаю, что есть библиотека, которая делает это

использовать Scalar :: Util qw (look_like_number);

пока я хочу сделать это с помощью регулярного выражения perl. И я хочу, чтобы он работал для двойных чисел, а не только для целых чисел.

так что я хочу что-то лучшее, чем это

$ var = ~ / ^ [+ -]? \ D + $ /

спасибо.

Ответы [ 3 ]

15 голосов
/ 11 мая 2011

Создание одного регулярного выражения для проверки числа действительно сложно.Просто слишком много критериев для рассмотрения. Perlfaq4 содержит раздел «Как определить, является ли скаляр числом / целым / целым / с плавающей точкой?

Код из этой документации показывает следующие тесты:

if (/\D/)                          {print "has nondigits\n"      }
if (/^\d+$/)                       {print "is a whole number\n"  }
if (/^-?\d+$/)                     {print "is an integer\n"      }
if (/^[+-]?\d+$/)                  {print "is a +/- integer\n"   }
if (/^-?\d+\.?\d*$/)               {print "is a real number\n"   }
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) {print "is a decimal number\n"}
if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) {
    print "is a C float\n"
}
  • Первый тест дисквалифицирует целое число без знака.
  • Второй тест квалифицирует целое число.
  • Третий тест квалифицирует целое число.
  • Четвертый тестквалифицирует положительное / отрицательное целое число со знаком.
  • Пятый тест квалифицирует действительное число.
  • Шестой тест квалифицирует десятичное число.
  • Седьмой тест квалифицирует число в cв стиле научной нотации.

Так что, если вы использовали эти тесты (исключая первый), вам нужно было бы проверить, что один или несколько тестов пройдены. Тогда у вас есть номер.

Другой метод, так как вы не хотите использовать модуль Scalar :: Util, вы можете узнать из кода IN Scalar :: Util. Функция look_like_number () настроена так:

sub looks_like_number {
  local $_ = shift;

  # checks from perlfaq4
  return $] < 5.009002 unless defined;
  return 1 if (/^[+-]?\d+$/); # is a +/- integer
  return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float
  return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) 
           or ($] >= 5.006001 and /^Inf$/i);

  0;
}

Вы должныбыть в состоянии использовать части этой функции, которые применимы к вашей ситуации.

Я хотел бы отметить, однако, что Scalar::Util является основным Perl-модулем;поставляется с Perl, как и strict.Лучше всего просто использовать его.

6 голосов
/ 11 мая 2011

Вы должны использовать Regexp :: Common, большинство шаблонов сложнее, чем вы думаете.

use Regexp::Common;

my $real = 3.14159;
print "Real" if $real =~ /$RE{num}{real}/;

Однако шаблон по умолчанию не привязан, поэтому более строгая версия:

my $real_pat = $RE{num}{real};
my $real     = 3.14159;
print "Real" if $real =~ /^$real_pat$/;
0 голосов
/ 11 мая 2011

Ну, во-первых, вы должны убедиться, что число не содержит запятых, поэтому сделайте следующее:

$ var = ~ s /, // g;# удалите все запятые

Затем создайте другую переменную, чтобы выполнить остальное сравнение.

$ var2 = $ var;

Затем удалите.из новой переменной, но только один раз.

$ var2 = ~ s /.//;# заменить.не с чем сравнивать пока только один раз.

теперь var2 должен выглядеть как целое число без "."сделайте так:

    if($var2 !~ /^[+-]?\d+$/){
        print "not valid";
    }else{
       #use var1 
    }

Вы можете исправить этот код и написать его как функцию, если вам нужно использовать его более одного раза.Ура!

...