Regex для проверки только натуральных чисел?

Недавно я обнаружил, что метод, который я использовал для проверки пользовательского ввода, принимает некоторые значения, которые меня не особенно устраивают. Мне нужно, чтобы он принимал только натуральные числа (1, 2, 3 и т. д.) без нецифровых символов.

Мой метод выглядит так:

function is_natural($str)
{
   return preg_match('/[^0-9]+$/', $str) ? false : $str;
}

Таким образом, он должен возвращать false, если находит что-то еще, кроме целого натурального числа. Проблема в том, что он принимает такие строки, как "2.3" и даже "2.3,2.2".


person soren.qvist    schedule 02.02.2011    source источник
comment
Что вы имеете в виду под натуральными числами, но без цифр? Как вам нужны числа без цифр?   -  person R. Martinho Fernandes    schedule 02.02.2011
comment
Это регулярное выражение не будет соответствовать точке или запятой.   -  person Koraktor    schedule 02.02.2011
comment
Я использую filter_var: stackoverflow.com/a/6563394/2165415 см. сообщение там   -  person T.Todua    schedule 01.03.2014
comment
возможный дубликат Проверить, является ли переменная натуральным числом   -  person T.Todua    schedule 01.03.2014


Ответы (4)


возможно, вы можете уточнить разницу между «числом» и «цифрой» ??

В любом случае, вы можете использовать

if (preg_match('/^[0-9]+$/', $str)) {
  // contains only 0-9
} else {
  // contains other stuff
}

или вы можете использовать

$str = (string) $str;
ctype_digit($str);
person Crayon Violent    schedule 02.02.2011
comment
Кажется, я неправильно понял цифры. Он должен принимать только цифры. Похоже, ctype_digit принимает только цифры в строковой форме, мне нужно, чтобы он принимал целые числа. - person soren.qvist; 02.02.2011
comment
да, ctype_digit() будет работать, однако обратите внимание, что я сначала привел $str как строку, потому что ctype_digit() всегда будет возвращать false, если вы передадите ей целое число. - person Crayon Violent; 02.02.2011
comment
ctype_digit() по-прежнему возвращает TRUE для таких строк, как «2.2,2.3». - person soren.qvist; 02.02.2011
comment
если ctype_digit() возвращает true для «2.2,2.3», то это ошибка PHP, которая должна быть обнаружена на bugs.php.net, но я не могу воспроизвести эту ошибку. - person Mark Baker; 02.02.2011
comment
Внимательно прочитайте: /^[0-9]+$/ принимает 0. Я рекомендую вместо этого использовать /^[1-9][0-9]*$/. - person Константин Ван; 29.02.2016
comment
@K._ оставляя в стороне тот факт, что вы комментируете пост пятилетней давности.. Я не уверен, к чему вы клоните.. вы предполагаете, что 0 не является числом? - person Crayon Violent; 29.02.2016
comment
@CrayonViolent Неважно, сколько лет сообщению, поскольку Google может привести кого-то (например, меня) к этому сообщению. Эм, во всяком случае. Я хочу сказать, что задавший вопрос искал регулярное выражение для натурального числа (ℕ). Прочтите этот пост: Является ли 0 натуральным числом? - person Константин Ван; 29.02.2016
comment
@K._ Хорошо, достаточно честно о прошлом, но я прочитал пост - и последующие комментарии в разных местах о том, чего действительно хотел ОП. Вы? Как из вопроса, так и из последующих комментариев ясно, что ОП не понимал, чего он на самом деле хотел. - person Crayon Violent; 01.03.2016
comment
@CrayonViolent См. «Мне нужно, чтобы он принимал только натуральные числа (1, 2, 3 и т. д.) без нецифровых символов». это то, что спрашивающий сказал в сообщении, а также в заголовке. Если вы считаете, что автор вопроса на самом деле этого не хотел, то почему бы вам не заставить его отредактировать пост? Комментарии в Stack Overflow предназначены не только только для вас, но и для спрашивающего. Вы рассматривали кого-то, кто будет читать этот пост? - person Константин Ван; 01.03.2016
comment
@K._, а затем в самой следующей части этого вопроса не было нецифровых символов, что не имеет смысла. И это еще не считая последующих комментариев. Слушай, чувак, я соглашусь, что вещи можно отредактировать/объединить, чтобы они соответствовали тому, как на самом деле обстояли дела в этой ветке, но, опять же, ты придираешься к какому-то случайному вопросу, который произошел давным-давно, и ты кричишь на кого-то, кто этого не делает. на самом деле не имеет ничего общего с тем, чтобы что-то редактировалось. Получить некоторую перспективу. Я закончил с этим разговором. ГЛХФ - person Crayon Violent; 01.03.2016

Проблема с /^[0-9]+$/ заключается в том, что он также принимает такие значения, как 0123. Правильное регулярное выражение — /^[1-9][0-9]*$/.

ctype_digit() страдает той же проблемой.

Если вам также нужно включить ноль, используйте вместо этого регулярное выражение: /^(?:0|[1-9][0-9]*)$/

person Koraktor    schedule 02.02.2011
comment
Нет ничего особенно вредного в том, чтобы принять 0123. Типа зависит от того, что он ожидает в целом, что он собирается с этим делать... но, например, 0123 будет оцениваться как 123 в расчетах и ​​т.д... - person Crayon Violent; 02.02.2011
comment
Натуральное число — это любое обычное число от 1 и выше (ℕ). Вот почему я думаю, что 0123 недействителен. - person Koraktor; 02.02.2011
comment
правда, но, как указал ОП, он запутался в определениях. Итак, опять же, все сводится к тому, для чего он на самом деле хочет его использовать. - person Crayon Violent; 02.02.2011
comment
Начальные нули слева от десятичной точки не более значимы, чем конечные нули справа от десятичной точки. - person tchrist; 02.02.2011
comment
@tchrist Они важны в тех случаях, когда анализатор чисел пытается автоматически определить восьмеричное число. Это означает, что 03 = 3, 11 = 11, но 011 = 9. - person Damian Yerrick; 23.01.2015

Вместо этого используйте ctype_digit().

person Mark Baker    schedule 02.02.2011

У меня возникла проблема с ctype_digit, когда номера счетов типа «000000196» должны были проходить через ctype_digit.

Итак, я использовал:

if (preg_match('/^[1-9][0-9]?$/', $str)) {
  // only integers
} else {
  // string
}
person vytsci    schedule 30.03.2018
comment
Этому вопросу семь лет, и на него уже есть принятый семилетний ответ. Более того, шаблон, который вы используете, уже был предложен другими пользователями. - person baduker; 30.03.2018