PHP Regex для человеческих имен

Ваше решение должно быть основано

  • Ваша фактическая потребность для них "больше функций"; и
  • Ваша ожидаемая стоимость реализации изменения.

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

, Если Ваше приложение требует очень сложной платформы журналирования, можно хотеть рассмотреть почему.

9
задан KdgDev 11 August 2009 в 16:48
поделиться

4 ответа

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

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

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

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

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


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

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

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

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


РЕДАКТИРОВАТЬ: если вы просто используете это регулярное выражение, оно не будет работать достаточно хорошо:

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

$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-инъекцию ... Но, вероятно, это символ, который разрешен в некоторых именах .. . Так что простого исключения некоторых символов может быть недостаточно; -)

у вас может получиться что-то вроде этого:

$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-инъекцию ... Но, вероятно, это символ, который разрешен в некоторых именах .. . Так что простого исключения некоторых символов может быть недостаточно; -)

у вас может получиться что-то вроде этого:

$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-инъекцию ... Но, вероятно, это символ, который разрешен в некоторых именах .. . Так что простого исключения некоторых символов может быть недостаточно; -)

Я определенно надеюсь, что мое собственное имя в порядке!)
И тот же пример с некоторыми специальными символами, например:

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

Будет сказано "плохая репутация"

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


Также обратите внимание, что одиночная кавычка может быть полезна при попытке выполнить SQL-инъекцию ... Но, вероятно, это символ, который разрешен в некоторых именах .. . Так что простого исключения некоторых символов может быть недостаточно; -)

Я определенно надеюсь, что мое собственное имя в порядке!)
И тот же пример с некоторыми специальными символами, например:

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

Будет сказано "плохая репутация"

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


Также обратите внимание, что одиночная кавычка может быть полезна при попытке выполнить SQL-инъекцию ... Но, вероятно, это символ, который разрешен в некоторых именах .. . Так что простого исключения некоторых символов может быть недостаточно; -)

21
ответ дан 4 December 2019 в 06:57
поделиться

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

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

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

4
ответ дан 4 December 2019 в 06:57
поделиться

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

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

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

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


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

6
ответ дан 4 December 2019 в 06:57
поделиться

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

2
ответ дан 4 December 2019 в 06:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: