Регулярное выражение для проверки правильности записи вещественного числа
Проверка правильности записи вещественного числа с помощью регулярного выражения PHP - не такая простая задача, какой она может показаться на первый взгляд. Введём следующее выражение (используется синтаксис PCRE):
/^(?:\+|\-)?\d+(?:\.\d+)?(?:e(?:\+|\-)?\d+)?$/i
Этот regexp скажет "да", если входная строка является допустимой записью вещественного числа. Здесь и далее регулярные выражения приведены в виде строки, которую можно использовать первым аргументом функции preg_match
или preg_match_all
, то есть, показанную выше строку нужно лишь заключить в двойные кавычки.
Увы, такое выражение не разрешает числа вроде
-1.
или .5
, запись которых разрешена в некоторых
языках программирования. Так что пришлось написать несколько более сложное регулярное выражение:
/^(?:\+|\-)?(?:(?:\d+)|(?:\d+\.)|(?:\.\d+)|(?:\d+\.\d+)){1}(?:e(?:\+|\-)?\d+)?$/i
Регулярное выражение удалось составить только "на всю строку" (шаблон начинается с метки начала строки ^
и заканчивается меткой конца $
), так что сначала бьём входные данные на лексемы, тоже с помощью регулярного выражения вида [\s,]+
(оно означает "разделитель или запятая").
Чтобы не зависеть от регистра символа "e
", оба выражения сделаны регистронезависимыми с помощью модификатора шаблона /i
.
Примеры из тестового прогона скрипта:
Array
(
[0] => -11e1
[1] => 2.3-e3
[2] => 2.1E-02
[3] => 14e
[4] => 12e2e2
[5] => 1E3
[6] => 1E-2
[7] => 1.4.5
[8] => 1-3
[9] => 1.3
[10] => -1.5
[11] => -2.5e-02
[12] => -1e-06
[13] => 1EE2
[14] => 1.01E003
[15] => -1.
[16] => .5
[17] => .
[18] => .e10
[19] => e1
[20] => -e5.
[21] => 2.E1
[22] => .5e3
)
Всего элементов: 23
Элемент 1 (-11e1): число -11e1
Элемент 2 (2.3-e3): не число
Элемент 3 (2.1E-02): число 2.1E-02
Элемент 4 (14e): не число
Элемент 5 (12e2e2): не число
Элемент 6 (1E3): число 1E3
Элемент 7 (1E-2): число 1E-2
Элемент 8 (1.4.5): не число
Элемент 9 (1-3): не число
Элемент 10 (1.3): число 1.3
Элемент 11 (-1.5): число -1.5
Элемент 12 (-2.5e-02): число -2.5e-02
Элемент 13 (-1e-06): число -1e-06
Элемент 14 (1EE2): не число
Элемент 15 (1.01E003): число 1.01E003
Элемент 16 (-1.): число -1.
Элемент 17 (.5): число .5
Элемент 18 (.): не число
Элемент 19 (.e10): не число
Элемент 20 (e1): не число
Элемент 21 (-e5.): не число
Элемент 22 (2.E1): число 2.E1
Элемент 23 (.5e3): число .5e3
Выполнить этот тестовый вызов онлайн
Перейти к онлайн-сервису для проверки вещественных чисел
Вот исходник основной части скрипта (может измениться в онлайн-версии):
<?php $data=''; if (isset($_GET['data'])) $data = strip_tags(trim($_GET['data'])); if (!isset($_GET['submit'])) { echo '<form method="get" action="'.$_SERVER['PHP_SELF'].'"> <input type="text" name="data" maxlength="128" size="128" value="'.$data.'"> <input type="submit" name="submit" value="OK"></form>'; } else { $array = preg_split ("/[\s,]+/",$data); print_r ($array); echo '<br>Всего элементов: '.count($array); $k=0; foreach ($array as $d) { echo '<br>Элемент '.++$k.' (<font color="red">'.$d.'</font>): '; $res=preg_match( "/^(?:\+|\-)?(?:(?:\d+)|(?:\d+\.)|(?:\.\d+)|(?:\d+\.\d+)){1}(?:e(?:\+|\-)?\d+)?$/i",$d); if ($res===false) echo 'ошибка в регулярном выражении!'; elseif ($res===0) echo 'не число'; else echo 'число '.$d; } echo '<br><a href="'.$_SERVER['PHP_SELF'].'?data='.urlencode($data).'">Вернуться</a>'; } ?>
Думаю, этот код может служить и примером организации небольшого сервиса, проверяющего вводимые пользователем строки на соответствие некоторому шаблону.
Ещё более простой код решения этой задачи без регулярных выражений
P.S. Позднее для проверки утверждения "Вся строка в Юникоде является вещественным числом" я пользовался вот таким регулярным выражением:
"/^(\+|\-)?(\d+\.?|\.\d+|\d+\.\d+)([eE](\+|\-)?\d+)?$/u"
Мой сервис для проверки регулярных выражений онлайн
02.04.2013, 13:13 [15525 просмотров]