Регулярное выражение для имен

Только начинаю исследовать «чудеса» регулярных выражений. Как человек, который учится методом проб и ошибок, я действительно борюсь, потому что мои испытания выдают непропорционально большое количество ошибок ... Мои эксперименты проводятся в PHP с использованием ereg ().

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

^[A-Z][a-zA-Z]+$  

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

  • Имена через дефис (Уортингтон-Смайт)
  • Имена с апостофиями (Д'Анджело)
  • Имена с пробелами (Ван дер Хамптон) - заглавные буквы в середине, которые могут потребоваться, а могут и не потребоваться, на данном этапе выходит за рамки моего интереса.
  • Совместные имена (Бен и Джерри)

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

Итак, я думаю, что суть в том, чтобы мое регулярное выражение также принимало пробелы, дефисы, амперсанды и апострофы - но не в начале или конце имени, чтобы быть технически правильным.

МОЖНО иметь имена через дефис с апострофами, например, O'Brien-O'Malley.

DOK 09.11.2008 00:00

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

Humpton 09.11.2008 00:06

Я был бы склонен избить своих родителей за то, что они обычно пишутся через дефис. Иметь необычную (читается: иностранную) фамилию - это уже плохо.

Matthew Scharley 09.11.2008 03:00

Если вы собираетесь требовать, чтобы первая буква была заглавной, может быть, было бы удобнее разрешить пользователю вводить строку, начинающуюся со строчной буквы, а затем использовать ее с заглавной буквы с помощью ucfirst ()?

RMD Developer 04.07.2011 12:44

возможный дубликат Регулярное выражение для проверки имен и фамилий?

outis 15.12.2011 05:19

Имейте в виду, что некоторые имена не начинаются с заглавной буквы, например «де ла Тур».

Matt Gibson 13.12.2014 18:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
26
6
99 822
25
Перейти к ответу Данный вопрос помечен как решенный

Ответы 25

если вы добавите пробелы, то допустимым именем будет «Он ходил на рынок в воскресенье».

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

О боже, а где же форма изменения имени - я полностью меняю свое имя на «H пошел на рынок в воскресенье».

Paul Tomblin 08.11.2008 23:46

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

Matthew Scharley 08.11.2008 23:49

Верно, моя попытка состоит не в том, чтобы найти имя в предложении или абзаце или в чем-то еще, а проверить на некоторое подобие нормальности.

Humpton 08.11.2008 23:56

Сдаться. Каждое правило, которое вы только можете придумать, имеет исключения в той или иной культуре. Даже если эта «культура» - это выродки, которые любят по закону менять свои имена на «37eet».

Ответ принят как подходящий
  • Имена через дефис (Уортингтон-Смайт)

Добавьте - во второй класс символов. Самый простой способ сделать это - добавить его в начале, чтобы его нельзя было интерпретировать как модификатор диапазона (как в a-z).

^[A-Z][-a-zA-Z]+$
  • Имена с апостофиями (Д'Анджело)

Наивный способ сделать это будет, как указано выше, давая:

^[A-Z][-'a-zA-Z]+$

Не забывайте, что вам может потребоваться экранировать его внутри строки! `` Лучший '' способ, учитывая ваш пример, может быть:

^[A-Z]'?[-a-zA-Z]+$

Что допустит возможный апостроф во второй позиции.

  • Имена с пробелами (Ван дер Хамптон) - заглавные буквы в середине, которые могут потребоваться, а могут и не потребоваться, на данном этапе выходит за рамки моего интереса.

Здесь у меня возникнет соблазн снова пойти по нашему наивному пути:

^[A-Z]'?[- a-zA-Z]+$

Потенциально лучшим способом может быть:

^[A-Z]'?[- a-zA-Z]( [a-zA-Z])*$

Которая ищет лишние слова в конце. Вероятно, это не очень хорошая идея, если вы пытаетесь сопоставить имена в теле дополнительного текста, но, опять же, оригинал тоже не справился бы с этим.

  • Совместные имена (Бен и Джерри)

На данный момент вы больше не смотрите на отдельные имена?

В любом случае, как видите, регулярные выражения имеют обыкновение очень быстро расти ...

Спасибо за шаг за шагом - я буду исследовать аналогично! Идея Бен и Джерри исходит из того, что я делаю то, что пары часто регистрируются как один пользователь. Я не хочу, чтобы то, что я делаю, разорвало "&", если они это сделают. Думаю, я могу понять, как это сделать, возможно, не в проверке фамилии.

Humpton 08.11.2008 23:52

Это не касается международных имен. В одном из комментариев ниже указано на использование \ p {L}, но вы можете прочитать намного больше о классах символов Юникода в regular-expressions.info/unicode.html

Kimball Robinson 18.08.2010 21:44

Хотя я никогда не говорил об этом прямо, это никогда не было попыткой решения, скорее, это была расширенная попытка показать, почему решение на самом деле неосуществимо. Имена слишком неоднозначны, чтобы их можно было проверить с какой-либо надежностью. Даже такая простая вещь, как ограничение длины, может пойти не так (я знаю кого-то, у кого имя состоит из одного символа).

Matthew Scharley 19.12.2012 18:13

Регулярные выражения Ruby on Rails Руководство по безопасности теперь предлагают не использовать начало и конец строки в проверках (^ и $), поскольку это угроза безопасности (возможно использование javascript). Вместо этого используйте начало / конец строки как \ A и \ z.

Andres Ehrenpreis 15.02.2016 20:36
^[A-Z][a-zA-Z '&-]*[A-Za-z]$ 

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

Это не учитывает международные символы.

Kimball Robinson 18.08.2010 21:42

В принципе, я согласен с Полом ... Вы всегда найдете исключения, такие как ди Каприо, DeVil и т. д.

Замечания к вашему сообщению: в PHP ereg обычно считается устаревшим (медленным, неполным) в пользу preg (регулярные выражения PCRE) .
И вам следует попробовать какой-нибудь тестер регулярных выражений, например мощный Regex тренер: они отлично подходят для быстрого тестирования RE с произвольными строками.

Если вам действительно нужно решить вашу проблему и вы не удовлетворены приведенными выше ответами, просто спросите, я попробую.

Во-первых, я добавлю в свой список изучение preg. Затем я исследую тестера. И я полностью согласен с тем, что такие люди, как ди Каприо, испортят мои первые размышления ... В этом есть реальная польза, но в основном это опыт обучения. То, что здесь появилось за считанные минуты, дало мне много возможностей для продолжения.

Humpton 09.11.2008 00:03

См. Этот вопрос для получения более подробной информации, связанной с "обнаружением имен".

регулярное выражение для соответствия максимум 4 пробела

По сути, у вас есть проблема в том, что фактически не существует символов, которые не могут образовать допустимую строку имени.

Если вы все еще ограничиваете себя словами без ä ü æ ß и других подобных нестрогих символов ascii.

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

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

Учебник по PHPBuilder очень старый и относится только к разновидности 'ereg' (или POSIX), которая устарела и планируется удалить в PHP 6. Вариант 'preg' (или PCRE) - это то, что вы должны использовать сейчас.

Alan Moore 16.01.2012 20:04

Я поддерживаю совет «сдаваться». Даже если вы рассмотрите числа, дефисы, апострофы и т. д., Что-то вроде [a-zA-Z] все равно не сможет уловить международные имена (например, те, которые имеют šđčćž, или кириллицу, или китайские иероглифы ...)

Но ... почему вы даже пытаетесь проверить имена? Какие ошибки вы пытаетесь отловить? Вам не кажется, что люди лучше вас умеют писать свое имя? ;) Серьезно, единственное, что вы можете сделать, пытаясь проверить имена, - это раздражать людей необычными именами.

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

fortboise 02.05.2012 18:37

Хотя я согласен, что будет почти невозможно написать регулярное выражение, которое допускает все "допустимые" имена, проверка цифр и специальных символов (таких как скобки, двойные кавычки и точки с запятой) обнаружит некоторые недопустимые входные данные (на стороне клиента) перед очисткой (сервер -сайд), чтобы предотвратить инъекцию.

Leandri 27.08.2014 15:53

@LeandriMidoriViviers - плохая идея бороться с инъекцией с помощью чего-либо, кроме подготовленных операторов, просто неразумно ограничивать ввод. Нет недопустимых вводов, и ваши «недопустимые символы» прекрасно иллюстрируют мою точку зрения - есть имена с цифрами (Майкл Ф. Джонсон 2-й), псевдонимы традиционно пишутся в двойных кавычках (Том «Iceman» Казанский), и я готов поспорить что какой-то сумасшедший думает использовать круглые скобки и точки с запятой, также называя своего ребенка. Подумайте обо всех маленьких столах Бобби в мире.

Domchi 28.08.2014 17:13

@Domchi Думаю, ты неправильно понял. Я не имел в виду, что проверка на недопустимый ввод предотвратит инъекцию, скорее, вы должны не только проверять на стороне клиента, но также дезинфицировать ввод на стороне сервера (используя подготовленные операторы, параметризованные запросы, экранирование строк, функции filter_input и т. д., Чтобы предотвратить внедрение ).

Leandri 28.08.2014 18:51

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

Leandri 28.08.2014 19:43

@LeandriMidoriViviers Согласен. В контексте тоже, но я не могу достаточно подчеркнуть, что вы никогда не знаете, что на самом деле является допустимым вводом в текстовые поля. Номера телефонов, имена, адреса ... просто оставьте их в покое, люди. Я не могу сосчитать, сколько раз какой-то сайт, ориентированный на США, настаивал на том, чтобы я указывал состояние, в котором у меня его нет в моем адресе, или пытался помешать мне ввести + в номер телефона или подобную чушь.

Domchi 29.08.2014 20:36

@Domchi Michael F. Johnson 2nd легко можно было бы написать Michael F. Johnson II. Есть еще пример с цифрами?

reformed 04.08.2017 17:30

@reformed Конечно. В Швеции была попытка назвать ребенка Brfxxccxxmnpcccclllmmnprxvclmnckssqlbb11116, есть американский рэпер Андре 3000 и американская журналистка Дженнифер 8. Ли. Некоторые страны США ограничивают имена, чтобы не включать цифры, но некоторые, например Кентукки, этого не делают, поэтому имена с цифрами вполне возможны. Также, пожалуйста, ознакомьтесь с этой отличной статьей: kalzumeus.com/2010/06/17/…

Domchi 05.08.2017 23:02

Вы можете использовать p {L} или \ pL вместо a-z для перехвата международных символов

Chimdi 09.05.2020 19:50

Хотя я согласен с ответами, в которых говорится, что вы в основном не можете сделать это с помощью регулярного выражения, я отмечу, что некоторые возражения (интернационализированные символы) могут быть разрешены с помощью строк UTF и класса символов \p{L} (соответствует "букве" Unicode) .

Вы можете узнать больше о юникоде и регулярных выражениях на regular-expressions.info/unicode.html

Kimball Robinson 18.08.2010 21:44

В regular-expressions.info/unicode.html говорится: «Чтобы сопоставить букву, включая любые диакритические знаки, используйте \ p {L} \ p {M} * +». Думаю, не работает на python.

dfrankow 18.06.2018 18:14

Это регулярное выражение идеально подходит для меня.

^([ \u00c0-\u01ffa-zA-Z'\-])+$

Он отлично работает в средах php с использованием preg_match (), но работает не везде.

Он соответствует Jérémie O'Co-nor, поэтому я думаю, что он соответствует всем именам UTF-8.

Да, я очень доволен, когда работаю в среде, где работает этот! : D

Daan 15.07.2014 02:10

Ошибка компиляции: PCRE не поддерживает \ L, \ l, \ N {name}, \ U или \ u со смещением 5

Theodore R. Smith 11.10.2017 09:22

Я получил ошибку как theodore, ошибка: Сообщение: preg_match (): Ошибка компиляции: PCRE не поддерживает \ L, \ l, \ N {name}, \ U или \ u со смещением 5

user8455694 29.10.2017 00:48

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

^[a-zA-Z][a-zA-Z0-9_]*\.?[a-zA-Z0-9_\.]*$

Длину струны можно установить отдельно.

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

Гений. Просто, уместно и элегантно. Я внесу некоторые изменения в эти выходные!

Humpton 24.03.2011 17:23

Это сработало для меня:

 +[a-z]{2,3} +[a-z]*|[\w'-]*

Это регулярное выражение будет правильно соответствовать таким именам, как следующие:

Жан-Клод Ван Дамм

Надин Арройо-Родрикес

Уэйн ла Пьер

Беверли д'Анджело

Билли-Боб Торнтон

Tito Puente

Сьюзан дель Рио

Он будет объединять в группы «van damme», «arroyo-rodriquez», «d'angelo», «billy-bob» и т. д., А также такие имена в единственном числе, как «wayne».

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

Я написал это для анализа имен приложения MapReduce. Все, что я хотел, - это извлечь слова из поля имени, сгруппировав del foo, la bar и billy-bobs в одно слово, чтобы сделать генерацию пары ключ-значение более точной.

/([\u00c0-\u01ffa-zA-Z'\-]+[ ]?[*]?[\u00c0-\u01ffa-zA-Z'\-]*)+/;

Попробуй это . Вы также можете принудительно начать с char, используя ^, и закончить char, используя $

Я использовал это, потому что имя может быть частью файла-патча.

//http://support.microsoft.com/kb/177506
foreach(array('/','\\',':','*','?','<','>','|') as $char)
  if (strpos($name,$char)!==false)
      die("Not allowed char: '$char'");

Это ужасно неэффективно.

reformed 04.08.2017 17:26

Я столкнулся с этой же проблемой, и, как и многие другие, которые писали, это не 100% -ое доказательство защиты от дурака, но оно работает для нас.

/([\-'a-z]+\s?){2,4}/

Это будет проверять наличие дефисов и / или апострофов в имени и / или фамилии, а также проверять наличие пробела между именем и фамилией. Последняя часть - небольшая магия, которая проверяет от 2 до 4 имен. Если у вас, как правило, много международных пользователей, у которых может быть 5 или даже 6 имен, вы можете изменить это число на 5 или 6, и это должно сработать для вас.

На самом деле это соответствует чему-либо от 2-х буквенного слова до 4-х слов.

eithed 16.04.2014 17:37

Я думаю, что "/ ^ [a-zA-Z '] + $ /" недостаточно, это позволит передать одну букву, мы можем настроить диапазон, добавив {4,20}, что означает диапазон букв от 4 до 20.

Чтобы улучшить ответ Даана:

^([\u00c0-\u01ffa-zA-Z]+\b['\-]{0,1})+\b$

допускает только одно появление дефиса или апострофии в пределах a-z и допустимых символов Unicode.

также выполняет возврат, чтобы убедиться, что в конце строки нет дефиса или апострофа.

Я придумал этот шаблон RegEx для имен:

/^([a-zA-Z]+[\s'.]?)+\S$/

Оно работает. Думаю, тебе тоже стоит им воспользоваться.

Он соответствует только именам или строкам, например:

Dr. Shaquil O'Neil Armstrong Buzz-Aldrin

Он не будет соответствовать строкам с двумя или более пробелами, например:

John  Paul

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

John Paul 

Текст выше имеет конечный пробел. Попробуйте выделить или выделить текст, чтобы увидеть пространство

Вот что я использую для изучения и создания ваших собственных шаблонов регулярных выражений:

RegExr: Leanr, сборка и тестирование RegEx

  • Попробуйте это:
    /^([A-Z][a-z]([ ][a-z]+)([ '-]([&][ ])?[A-Z][a-z]+)*)$/
  • Демо: http://regexr.com/3bai1

Хорошего дня !

ЛУЧШИЕ ВЫРАЖЕНИЯ REGEX ДЛЯ ИМЕНИ:

  • Я буду использовать термин особый персонаж для обозначения следующих трех символов:
    1. Тире -
    2. Дефис '
    3. Точка .
  • Пробелы и специальные символы не могут появляться дважды подряд (например: - или '. или ..)
  • Обрезано (без пробелов до и после)
  • Пожалуйста ;)

Обязательное одиночное имя, БЕЗ пробелов, БЕЗ специальных символов:

^([A-Za-z])+$
  • Сьерра действителен, Джек Александр недействителен (имеет пробел), О'Нил недействителен (имеет специальный символ)

Обязательное одиночное имя, БЕЗ пробелов, специальные символы С:

^[A-Za-z]+(((\'|\-|\.)?([A-Za-z])+))?$
  • Сьерра действителен, О'Нил действителен, Джек Александр недействителен (имеет пробел)

Обязательное одиночное имя, пробелы необязательные дополнительные имена, С, СО спецсимволами:

^[A-Za-z]+((\s)?((\'|\-|\.)?([A-Za-z])+))*$
  • Джек Александр действителен, Сьерра О'Нил действителен

Обязательное одиночное имя, пробелы необязательные дополнительные имена, С, специальные символы БЕЗ:

^[A-Za-z]+((\s)?([A-Za-z])+)*$
  • Джек Александр действителен, Сьерра О'Нил недействителен (имеет специальный символ)

ОСОБЫЙ СЛУЧАЙ

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

Обязательное одиночное имя + необязательные дополнительные имена + пробелы + специальные символы:

^(\s)*[A-Za-z]+((\s)?((\'|\-|\.)?([A-Za-z])+))*(\s)*$

Добавьте свои собственные специальные символы

Если вы хотите добавить свои собственные специальные символы, скажем, подчеркивание _, это группа, которую вам нужно обновить:

(\'|\-|\.)

К

(\'|\-|\.|\_)

PS: Если у вас есть вопросы, прокомментируйте здесь, и я получу электронное письмо и отвечу;)

Спасибо за это. Было предложение: текущее регулярное выражение не соответствует таким именам, как «Роберт Дауни-младший». которые заканчиваются специальным символом - регулярному выражению требуется ([A-Za-z]) * вместо ([A-Za-z]) + ... поэтому окончательное регулярное выражение выглядит как ^ (\ s) * [A- Za-z] + ((\ s)? ((\ '| \ - | \.)? ([A-Za-z]) *)) * (\ s) * $

Jaspal Singh 12.07.2017 18:15

Лучшее для меня.

Chimdi 09.05.2020 21:18

вы можете использовать это ниже для имен

^[a-zA-Z'-]{3,}\s[a-zA-Z'-]{3,}$

^ начало строки

$ конец строки

\s пространство

[a-zA-Z'-\s]{3,} примет любое имя длиной 3 символа или более, и он будет включать имена с ' или -, такие как jean-luc.

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


в случае нескольких имен вы можете добавить \s

^[a-zA-Z'-\s]{3,}\s[a-zA-Z'-]{3,}$

Проверь это:

^(([A-Za-z]+[,.]?[ ]?|[a-z]+['-]?)+)$

regex

Можете протестировать здесь: https://regex101.com/r/mS9gD7/46

Попробуйте это регулярное выражение:

^[a-zA-Z'-\s\.]{3,20}\s[a-zA-Z'-\.]{3,20}$

Ответ Аомине был весьма полезен, я немного изменил его, чтобы включить:

  1. Имена с точками (посередине): Jane J. Samuels

  2. Имена с точками в конце: John Simms Snr.

Также имя будет принимать минимум 2 буквы и мин. из 2 букв для фамилии, но не более 20 для каждой (итого 40 символов)

Успешные тестовые случаи:

D'amalia Jones    
David Silva Jnr.    
Jay-Silva Thompson
Shay .J. Muhanned
Bob J. Iverson

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

Он гибкий - вы можете добавлять / удалять символы, которые вы хотите в выражении (с акцентом на символы, которые вы хотите отклонить, а не включать).

^(?:(?!^\s|[ \-']{2}|[\d\r\n\t\f\v!"#$%&()*+,\./:;<=>?@[\\\]^_`{|}~€‚ƒ„…†‡ˆ‰‹‘’“”•–—˜™›¡¢£¤¥¦§¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿×÷№′″ⁿ⁺⁰‱₁₂₃₄]|\s$).){1,50}$

Соответствие регулярному выражению: от 1 до 50 международных букв, разделенных одним разделителем (пробел - ').

Regex отклоняет: пустой префикс / суффикс, последовательные разделители (пробел - '), цифры, новая строка, табуляция, ограниченный список расширенных символов ASCII

Демо

Другие вопросы по теме