Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Как отличить число от не-числа?


Автор: ilya_evseev 30.10.2004, 10:49
Как определить, что переменная содержит число?
Сейчас я пытаюсь сделать это так:

sub enquote_value($) {
$_ = shift;
no warnings 'numeric';
return $_ unless ($_ == 0) && ($_ ne "0");
s/'/\\'/g; # escape internal quotes..
'\'' . $_ . '\''; # put external quotes..
}

Однако этот вариант считает, например, ip-адрес числом.

P.S. Зачем мне это потребовалось? Чтобы при конструировании SQL-запроса строковые поля заключать в кавычки, а числовые - нет. Если определить по значению, число это или нет, Перл не позволяет, во все подпрограммы придётся отдельным параметром сообщать типы столбцов - слишком монстроидально.

Автор: Forza 30.10.2004, 11:24
Натрави на него регэксп, который зависит от формата того, что хочешь считать числами.
Например, проверка
Код
if ($number =~ /^[+-]?\d+$/)
{ print ("it is целое число"); }
определит является ли содержимое строки целым числом, в начале которого может стоять плюс, минус или вообще ничего. Ессно, надо предварительно убрать возможные пробелы с начала и конца или проверять с учётом их:
Код
if ($number =~ /^\s*[+-]?\d+\s*$/)
{ print ("it is целое число"); }


Если же числа могут быть как дробными, так и целыми, то подойдёт такая проверка:
Код
if ($number =~ /^\s*[+-]?\d+(\.\d+)?\s*$/)
{ print ("it is число"); }

Т.е. тут после целой части может быть, а может и не быть точка с как минимум одним числом.

Если хочешь также считать числами строки типа ".123" или "1.23E-01", то придумывай сам им регэкспы. :)

Автор: Secandr 30.10.2004, 11:32
Код
if (($a+0) eq $a) {print "число";}
или
if (($a+0) == $a) {print "число";}


Надо тестить.
Добавлено @ 11:33
Forza Проще надо быть....

Автор: Forza 30.10.2004, 12:14
Secandr, согласен. А то я привык всё подряд проверять регэкспами. Очень уж они мне нравятся! :)

Имхо из предложенного тобой надо брать вариант со сравнением через "==", т.к. мы пытаемся воспринимать переменную именно как число!

Автор: Secandr 30.10.2004, 15:10
Forza Насамом деле должны работать оба способа.

А с регекспами знакомая ситуация. Скорей всего ты их нежавно выучил :)

Вещь класная, я сам с полгода искал простые слова регекспами :) Но вроде стал отходить...

Автор: Nobody 30.10.2004, 18:50
Код
$a += 0;


Отныне $a - число :)

Автор: ilya_evseev 31.10.2004, 02:56
Да, мне эта идея самому пришла голову, едва я встал из-за компьютера: арифметически прибавить ноль и строково сравнить с оригиналом - если равно, то это число. Отрадно было увидеть, что рецепт от крутых перцев совпал с моим вариантом, который в результате выглядит так:
Код

sub dbi_quote($$) {
   my $dbh = shift;
   $_ = shift;

   no warnings 'numeric';
   return $_ if (($_ + 0) eq $_);

   return $dbh->quote($_) if $dbh;

   s/'/''/g;   # escape internal quotes..
   '\'' . $_ . '\'';   # put external quotes..
}

Что касается регэкспов, то описывать ими форматы чисел, на мой взгляд, нерационально: они могут быть и вещественные, и целые, и 16-ричные и хрен знает какие ещё. Получается и громоздко, и ненадёжно, и без помощи Перла.

Автор: Secandr 31.10.2004, 09:55
Nobody
Код
$a += 0;

Я тоже всегда так делаю, это позволяет избежать проверок.

А проверка правельнее
Код
if (($a+0) eq $a) {print "число";}


Поскольку в случае

Код
if (($a+0) == $a) {print "число";}


$a='fuck' будет числом :)

Автор: Sadok 2.11.2004, 15:49
ilya_evseev
Цитата

Чтобы при конструировании SQL-запроса строковые поля заключать в кавычки, а числовые - нет.

use DBI;
my $db = DBI -> connect ('DBI:mSQL:mydata', user, pass);
my $string = "Bla-bla";
my $string2 = "123";
my $qs = $db -> quote($string);
my $qs2 = $db -> quote($string2);
# теперь обе строки годятся для использования в командах для своих СООТВЕТСТВУЮЩИХ серверов баз данных

Автор: ElectricalStorm 2.11.2004, 19:24
ИМХО Forza единственно правильный совет дал ...

Автор: Secandr 2.11.2004, 20:44
ElectricalStorm Политически корректнее брать eq

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)