Мне нужно регулярное выражение PHP для проверки формата строки 5 цифр, одна запятая - PullRequest
1 голос
/ 20 апреля 2011

У меня есть огромное поле ввода PHP на веб-странице. Этот ввод должен состоять только из 5 цифр, разделенных запятыми:

00100,00247,90277,97030,00657

обратите внимание, что последний не имеет запятой в конце.

Есть ли регулярное выражение, которое может это сделать? Поскольку поле ввода очень большое и может содержать более 100 таких элементов, я хочу проверить его на стороне сервера PHP, прежде чем запрашивать базу данных, и это позволит избежать любых попыток SQL-инъекции.

Запрос выполняется, только если в последовательности только 5 чисел и запятая, за исключением последнего. Кстати, это государственные идентификационные номера системы водоснабжения.

Ответы [ 6 ]

7 голосов
/ 20 апреля 2011

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

/^(?:\d{5},)*\d{5}$/

Это будет соответствовать только 1 или более 5-значным числам, разделенным запятой без пробелов.

3 голосов
/ 20 апреля 2011

Поскольку это данные, представленные пользователем, ваша проверка должна быть более гибкой. Что если пользователь случайно поставит пробел после одной из запятых? Или вставляется разрыв строки?

Я понимаю, что вы ищете решение для регулярных выражений, но я могу предложить использовать explode для создания массива и применения правила к каждому элементу. Разделение их на элементы обеспечивает большую гибкость при проверке и хранении:

$nums = explode(',', '00100,00247,90277,97030,00657');
foreach ($nums as $num) {
    if (!preg_match('/^\d{5}$)/', trim($num))) {
        // error!
    }
}
0 голосов
/ 20 апреля 2011

Это может работать:

/^\d{5}(?:,\d{5})*$/

edit 1 заметил, что ridgerunner имеет тот же ответ, поэтому не обращайте на это внимания.


редактировать 2 некоторые заметки о производительности.

Анализ отказов

Возврат возвращает при сбое:

^\d{5}(?:,\d{5})*$ возвращает ,\d{5}
^(?:\d{5},)*\d{5}$ возвращает \d{5},

Post Backtracking регрессивные проверки топографии:
(После возврата backtracking справа от того, который вернул), чеки находятся

^\d{5}(?:,\d{5})*$ проверкидля $
^(?:\d{5},)*\d{5}$ проверок для \d{5}$

Победитель: ^ \ d {5} (?:, \ d {5}) * $

без возврата регулярных выражений (с использованием позитивного квантификатора +):

^\d{5}(?:,\d{5})*+$ ничего не дает обратно, немедленно отказывает
^(?:\d{5},)*+\d{5}$ не возвращает ничего, немедленно отказывает

Тесты

Использование строки из 50 блоков \d{5},.
Строка выборки сопоставляется с каждым регулярным выражением в цикле 100 000 раз.
Ошибка была вызвана в концестрока, удаленная для теста на успех.

Успех:
Все заняло 1 секунду, чтобы завершить успешный пробег.

Отказ, возврат:
^\d{5}(?:,\d{5})\*$ заняло 1,2 секунд лучший
^(?:\d{5},)\*\d{5}$ взял 1,6 секунд

Отказ, без возврата:
^\d{5}(?:,\d{5})*+$ заняло .9 секунд
^(?:\d{5},)*+\d{5}$ заняло .9 секунд

Выводы

Возврат - Поставьте наименьшую проверку после возврата
после подвыражения возврата.В этом случае наименьшее значение
составляет $.
. В общем случае ставьте обязательные выражения впереди из необязательных.
Best ^ \ d {5} (?:, \ d {5}) * $

Без возврата - Неважно.
^\d{5}(?:,\d{5})*+$ или ^(?:\d{5},)*+\d{5}$

0 голосов
/ 20 апреля 2011

Simple. Это регулярное выражение соответствует значению, имеющему одно или несколько пятизначных чисел, разделенных запятыми:

if (preg_match('/^\d{5}(\s*,\s*\d{5})*$/', $value)) {
    // Good value
}

Позволяет также использовать пробелы между числами.

0 голосов
/ 20 апреля 2011

Я думаю, вам скорее нужно str_getcsv:

while ($row = str_getcsv($fp)) {
    // $row is an array containing your digits
}
0 голосов
/ 20 апреля 2011

Я бы взорвал его и проверил каждую строку отдельно:

$input = '00100,00247,90277,97030,00657';
$input_array = explode(',', $input);
$is_valid = true;

foreach ($input_array as $number) {
  if (preg_match("/\\d/", trim($number)) != strlen(trim($number))) {
    $is_valid = false;
  }
}

print($is_valid);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...