PHP Regex для имен людей

У меня возникла проблема с регулярным выражением, которое я использую для имен людей.

$rexName = '/^[az' -]$/i'; 

Предположим, что пользователь с именем Юрген хочет зарегистрироваться? Или Бёб? Это довольно распространенное явление в Европе. Есть ли специальные обозначения для этого?

EDIT: просто бросил имя Юргена против создателя регулярных выражений, и он разбивает слово на букву ü …

http://www.txt2re.com/index.php3?s=J%FCrgen+Blalock&submit=Show+Matches

EDIT2: Хорошо, так как проверка таких конкретных вещей сложна, почему бы не использовать регулярное выражение, которое просто проверяет наличие недопустимых символов?

 $rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i"; 

(теперь какие из них действительно могут быть использованы при любой попытке взлома?)

Например. Это позволяет «и – знаки», но вам нужно; чтобы он работал в SQL, и они будут остановлены. Все другие символы, которые обычно используются для HTML-инъекций SQL-атак, которые мне не хватает?

Related of "PHP Regex для имен людей"

Я бы действительно сказал: не пытайтесь утверждать имена: однажды или иначе ваш код встретит имя, которое, по его мнению, «неправильно» … И как вы думаете, что кто-то будет реагировать, когда приложение скажет ему « ваше имя недействительно "?

В зависимости от того, чего вы действительно хотите достичь, вы можете использовать какой-то черный список / фильтры, чтобы исключить «не-имена», о которых вы подумали: возможно, пусть некоторые «плохие имена» пройдут, но, по крайней мере, это не должно препятствовать доступу существующего имени к вашему приложению.

Вот несколько примеров правил, которые приходят на ум:

  • нет номера
  • нет специального символа, например "~{()}@^$%?;:/*§£ø и, возможно, некоторые другие
  • не более трех пространств?
  • ни один из «админ», «поддержка», «модератор», «тест» и несколько других очевидных неименований, которые люди склонны использовать, когда они не хотят вводить свое настоящее имя …
    • (но, если они не хотят давать вам свое имя, их все равно не будет, даже если вы запретите им печатать какие-то случайные буквы, они могут просто использовать настоящее имя … Что не их)

Да, это не идеально; и да, это позволит пропускать некоторые имена без имени … Но это, вероятно, лучше для вашего приложения, чем сказать кому-то «ваше имя неверно» (да, я настаиваю ^^)

И, чтобы ответить на комментарий, вы оставили еще один ответ:

Я мог бы просто запретить большинство командных символов для SQL-инъекций и атак XSS,

Что касается SQL Injection, вы должны избежать своих данных перед отправкой их в базу данных; и, если вы всегда избегаете этих данных (вы должны!), вам не нужно заботиться о том, что пользователи могут вводить или нет: поскольку он экранирован, всегда нет риска для вас.

То же самое касается XSS: поскольку вы всегда избегаете своих данных при его выводе (вы должны!), Нет риска инъекции 😉


EDIT: если вы просто используете это регулярное выражение, это не сработает хорошо:

Следующий код:

 $rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i"; if (preg_match($rexSafety, 'martin')) { var_dump('bad name'); } else { var_dump('ok'); } 

Вы получите хотя бы предупреждение:

 Warning: preg_match() [function.preg-match]: Unknown modifier '{' 

Вы должны избегать хотя бы некоторых из этих специальных символов; Я позволю вам копать в PCRE Patterns для получения дополнительной информации (есть много чего узнать о PCRE / regex, и я не смогу объяснить все это)

Если вы действительно хотите проверить, что ни один из этих символов не находится внутри данной части данных, вы можете получить что-то вроде этого:

 $rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i"; if (preg_match($rexSafety, 'martin')) { var_dump('bad name'); } else { var_dump('ok'); } 

(Это быстрое и грязное предложение, которое нужно уточнить!)

Это говорит «ОК» (ну, я определенно надеюсь, что мое собственное имя в порядке!)
И тот же пример с некоторыми специальными символами, например:

 $rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i"; if (preg_match($rexSafety, 'ma{rtin')) { var_dump('bad name'); } else { var_dump('ok'); } 

Скажет «плохое имя»,

Но, пожалуйста, обратите внимание, что я не полностью протестировал это, и, вероятно, вам нужно больше работать! Не используйте это на своем сайте, если вы не проверили его очень внимательно!

Также обратите внимание, что одна цитата может быть полезна при попытке выполнить SQL Injection … Но это, вероятно, символ, который является законным в некоторых именах … Поэтому просто исключить некоторые символы может быть недостаточно 😉

Реализация PCRE в PHP поддерживает свойства символа Юникода, которые охватывают более широкий набор символов. Таким образом, вы можете использовать комбинацию \p{L} (буквенные символы), \p{P} (знаки пунктуации) и \p{Zs} (символы разделителя пробелов):

 /^[\p{L}\p{P}\p{Zs}]+$/ 

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

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


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

Используйте mysql_real_escape_string или подготовленные операторы для SQL-запросов, htmlspecialchars для вывода HTML и другие соответствующие функции для других языков.

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

Вы можете сделать это, используя:

$ regexp = "/ ^ [ ^ <помещать ненужные символы здесь> ] + $ /

Если вы пытаетесь разобрать человеческое имя в PHP, я повторяю сценарий nameparse.php Кита Бекмана .