Regex - вернуть имя и фамилию - PullRequest
2 голосов
/ 02 ноября 2009

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

$name = preg_replace('~\b(\p{L}+)\b.+\b(\p{L}+)\b~i', '$1 $2', $name);

Ожидаемый результат должен быть примерно таким:

William -> William // Regex Fails
William Henry -> William Henry
William Henry Gates -> William Gates

Я также хочу, чтобы поддерживал акценты , например "João".

РЕДАКТИРОВАТЬ: Я понимаю, что некоторые имена не будут идентифицированы должным образом, но это не проблема для меня, так как это будет использоваться на локальном сайте, где последнее слово это фамилия (хотя, возможно, и не вся фамилия), но это не проблема, поскольку все, что я хочу, - это быстрый способ сказать "Уважаемый FIRST_NAME LAST_NAME" ... Так что все эти обсуждения, хотя и полностью действительны для меня бесполезно.

Может кто-нибудь помочь мне с этим?

Ответы [ 7 ]

7 голосов
/ 02 ноября 2009

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

6 голосов
/ 02 ноября 2009

Вместо регулярного выражения вам может быть проще сделать что-то вроде:

$parts = explode(" ", $name);
$first = $parts[0];
$last = ""
if (count($parts) > 1) {
    $last = $parts[count($parts) - 1];
}

Возможно, вы захотите заменить несколько последовательных битов пробела сначала одним пробелом, чтобы не получать пустые биты и избавиться от конечных / ведущих пробелов:

$name = ereg_replace("[ \t\r\n]+", " ", trim($name));
2 голосов
/ 02 ноября 2009

Как и вам, вам нужна фамилия, которой, конечно, нет в вашем первом примере.

Используйте кластеризованную группировку, (?:...) и счетчик 0-или-1, ?, для отчества и фамилии в целом, чтобы они были необязательными:

'~\b(\p{L}+)\b (?: .+\b(\p{L}+)\b )?~ix'  # x for spacing

Это должно позволять захватывать первое имя независимо от того, даны ли отчество / фамилия.

$name = preg_replace('~\b(\p{L}+)\b(?:.+\b(\p{L}+)\b)?~i', '$1 $2', $name);
2 голосов
/ 02 ноября 2009

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

И затем у вас есть такие вещи, как суффиксы (младший, старший, III и т. Д.) И префиксы (мистер, миссис и т. Д.), Объединенные имена (например, Джон и Мэри Смит). Как уже упоминали некоторые другие, вам также приходится иметь дело с несколькими частями фамилии (например, Виктор де ла Хойя).

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

1 голос
/ 02 ноября 2009

Я думаю, что ваш лучший вариант - просто относиться ко всему после имени как к фамилии, т.е.

Уильям Генри Гейтс
Имя: Уильям
Фамилия: Генри Гейтс

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

1 голос
/ 02 ноября 2009

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

Однако, в зависимости от контекста / сферы действия, которое вы делаете, вам может понадобиться переоценить вещи - не все имена в мире будут соответствовать этому шаблону.

0 голосов
/ 01 июня 2018

Вот простой не-регулярный способ

$name=explode(" ",$name);
$first_name=reset($name);
$last_name=end($name);
$result=$first_name.' '.$last_name;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...