Почему соответствует номерам и буквам?

Я хочу переменную, которая допускает letters and only не digits .

И эта переменная может находиться в любой позиции в строке.

Посмотри на это,

 $pattern = '~user/(:var)~'; $pattern = str_replace('(:var)', '([a-zA-Z])', $pattern); // Note, the variable contain both numbers and letters $test = 'user/dave123'; $r = preg_match($pattern, $test); var_dump($r); //1 Success (I don't want this) 

Все, что я хочу,

Если переменная содержит только буквы, то preg_match() должен возвращать 1 , но если он содержит хотя бы одну цифру, то preg_match() должен немедленно возвращать 0,

Какое regex должно быть определено вместо ([a-zA-Z]) и почему ([a-zA-Z]) соответствует как числам, так и буквам !?

Регулярное выражение соответствует этой подстроке вашего тестового значения: user/d .

Если вы хотите проверить всю строку, добавьте к вашему шаблону стартовые ( ^ ) и end ( $ ) привязки:

 $pattern = '~^user/(:var)$~'; 

Чтобы проверить начало / конец строки ИЛИ другого разделителя, например / , он будет выглядеть так:

 $pattern = '~(?:^|/)user/(:var)(?:$|/)~'; 

Это заставит его рассмотреть всю ценность до тех пор, пока ни конец, ни следующий / … предотвращающий частичные совпадения, как вы столкнулись в вашем вопросе.

(Символ ?: Указывает группу, не связанную с захватом , а это означает, что дополнительные () группы не попадут в итоговый список совпадений)

Вам также необходимо разрешить классу [a-zA-Z] повторять с + или он будет соответствовать только односимвольным именам пользователей:

 $pattern = str_replace('(:var)', '([a-zA-Z]+)', $pattern); 

Вам нужно дать начало финалу, используя ^ и $ соответственно.

 '~^user/(:var)$~' 

Он совпадает, потому что у вас есть user , dave в вашей строке.

Ваш шаблон означает «один из символов между az или AZ», поэтому он соответствует. Он не предлагает проверку, чтобы убедиться, что это единственное , что соответствует, и оно не будет соответствовать повторяющимся символам.

Вместо этого подхода, почему бы не попробовать что-то более простое. Поскольку все, что вы хотите знать, это если строка содержит номер или нет:

 $haystack = 'user/dave123'; foreach(range(0,9) as $i) { if (strpos($haystack,$i) === FALSE)) { return 1; } } return 0; 

Это остановится при первом найденном номере.

Возможно, что шаблон соответствует первому символу в строке и не соответствует всей строке. Чтобы сопоставить всю строку, попробуйте

"/^[az]+$/i"

который должен давать вам регистр, нечувствительный к регистру, только по всей строке ( ^ и $начало строки и конец символов разделителя строк ).

Есть также некоторые удобные встроенные функции PHP, такие как ctype_alpha() которые делают точно то же самое.