Я использую это регулярное выражение PHP, чтобы проверить true / false, содержит ли поле имя, состоящее как минимум из имени / фамилии, а затем, необязательно, других отчеств или инициалов.
$success = preg_match("/([\x{00c0}-\x{01ff}a-zA-Z'-]){2,}(\s([\x{00c0}-\x{01ff}a-zA-Z'-]{1,})*)?\s([\x{00c0}-\x{01ff}a-zA-Z'-]{2,})/ui",$user['name'],$matches);
$output[($success ? 'hits' : 'misses')][] = ['id' => $user['id'],'email' => $user['email'],'name' => $user['name'],'matches' => $matches];
Кажется, работает хорошо с точки зрения попаданий / промахов, то есть истина / ложь, независимо от того, совпадает или нет.
Но затем я пытаюсь использовать то же самое для извлечения имени и фамилии, используя группы, которые я изо всех сил пытаюсь получить право ..
Получить много результатов, таких как:
"name": "Jonny Nott",
"matches": [
"Jonny Nott",
"y",
"",
"",
"Nott"]
"name": "Name Here",
"matches": [
"Name Here",
"e",
"",
"",
"Here"]
"matches": [
"Jonathan M Notty",
"n",
" M",
"M",
"Notty"]
..но я действительно хочу, чтобы одно из совпадений всегда содержало только имя, а другое — только фамилию.
Любые указатели относительно того, что не так?
Всякий раз, когда вы определяете группа захвата в регулярном выражении соответствующая ему часть строки добавляется как отдельный элемент в результирующий массив. Есть две стратегии, чтобы избавиться от них:
(a)+
=> a+
)(\s+\w+)+
=> (?:\s+\w+)+
)Кроме того, в вашем случае вы можете улучшить шаблон, если вы замените часть, соответствующую букве, на \p{L}
Класс свойств Unicode, который соответствует любым буквам.
использование
/[\p{L}'-]{2,}(?:\s[\p{L}'-]+)?\s[\p{L}'-]{2,}/u
Увидеть regex demo
Здесь осталась только одна группировка, (?:...)
и это необязательно, ?
после того, как это делает это соответствует 1 или 0 раз.
подробности
[\p{L}'-]{2,}
— 2 или более букв, '
или же -
(?:\s[\p{L}'-]+)?
— 1 или 0 вхождений пробела, а затем 1 или более букв, '
или же -
\s
— пробел[\p{L}'-]{2,}
— 2 или более букв, '
или же -
Пытаться:
(?P<firstName>[\x{00c0}-\x{01ff}a-zA-Z'-]{2,})(\s([\x{00c0}-\x{01ff}a-zA-Z'-]{1,})*)?\s(?P<lastName>[\x{00c0}-\x{01ff}a-zA-Z'-]{2,})
Главная ошибка, которую вы повторили, первая группа {2,} — не первый диапазон
Используйте группы без захвата (?:...)
всякий раз, когда вам нужно использовать круглые скобки, но вы не хотите сопоставлять эту часть (например, часть пробелов и отчество) и включать квантификатор в группу захвата, а не только символы для сопоставления (например, для имени {2,}
должен быть в группе захвата).
([\x{00c0}-\x{01ff}a-zA-Z'-]{2,})(?:\s(?:[\x{00c0}-\x{01ff}a-zA-Z'-]{1,})*)?\s([\x{00c0}-\x{01ff}a-zA-Z'-]{2,})