Регулярное выражение плохо проверяет пароли

Мне нужно проверить, содержат ли пароли ТОЛЬКО АНГЛИЙСКИЕ цифры и буквы. Я использую следующее регулярное выражение:

if (!preg_match("^[A-Za-z0-9 _]*$^", $_POST['password']))
{
// show error
}
{

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


person Mostafa Talebi    schedule 30.11.2013    source источник
comment
используйте !preg_match('^[a-zA-Z0-9 _]+$') и не забудьте использовать else   -  person Iłya Bursov    schedule 30.11.2013


Ответы (4)


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

Используйте regexpal.com для проверки вашего регулярного выражения.

На самом деле я бы изменил это на это:

if (preg_match("[^A-Za-z0-9 _]", $_POST['password']))
{
  // invalid character
}
person Noam Rathaus    schedule 30.11.2013
comment
Это быстро, но также позволяет использовать пустые пароли, поэтому вам, вероятно, также понадобится проверка длины перед этим. - person Arc; 30.11.2013
comment
Также нет разделителей - person Arc; 02.12.2013

Нет такой вещи, как «АНГЛИЙСКАЯ» цифра или буква. Многие языки пишутся (или могут писаться) с использованием того же алфавита, что и английский. Его обычно называют латинским алфавитом.

Если вы действительно хотите принимать только латинские буквенно-цифровые символы, используйте:

if preg_match("/^[a-zA-Z0-9]+$/", $_POST['password']) {
  //good to go
} else {
  //I don't like this password
}

Ваше исходное регулярное выражение имеет дополнительный конечный ^ и допускает пробелы и символы подчеркивания. Вы хотите, чтобы эти символы также были разрешены? Если это так, используйте ^[\w ]+$.

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

Если вы проверяете слабые пароли, не обращайте на них внимания. Однако есть и другие факторы, которые следует учитывать, например, длина и наличие словарных слов. См. этот ответ для некоторых отличных деталей.

Кстати, храните ли вы пароли своих пользователей в хешированной форме? Это абсолютная необходимость.

person joews    schedule 30.11.2013

Пытаться

preg_match('/^[\w]+$/', $_POST['password'] ) instead ! 

Альтернатива:

preg_match("/^[a-zA-Z0-9]+$/", $_POST['password'])
person Prashant Ghimire    schedule 30.11.2013
comment
Отсутствует + в первом регулярном выражении! ;) - person Ismael Luceno; 30.11.2013

preg_match() и подобные используют разделитель, установленный в первом символе. Это завершит регулярное выражение, после чего строка должна закончиться или может указывать только модификаторы.

Таким образом, ваш код должен быть, например.

if (!preg_match('`^[A-Za-z0-9 _]+$`', $_POST['password']))
{
// show error
}
{

Вы использовали ^ в качестве разделителя, но должны использовать его, чтобы ваше регулярное выражение совпадало с начала строки, поэтому я использую обратную кавычку `, поскольку она редко используется в строке (другие использовали бы /).

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

Еще одна вещь: сопоставление [...]* также позволит использовать пустые пароли, которые вы не должны поощрять, поэтому + (хотя это спорно, если вы предпочитаете пароли, содержащие не менее n символов, т. е. сопоставление с использованием [...]{n,}).

person Arc    schedule 30.11.2013