Нужна помощь с жестким регулярным выражением

Мне нужно регулярное выражение, которое проверяет, содержит ли строка только буквы (az) и что первая буква в верхнем регистре, вы не можете иметь 2 буквы в верхнем регистре слова. Например: THomas или THomAS, но Томас Андерсон (Томас Андерсон тоже) будет действительным

Посмотрите:

The Magician Of The Elfs будет действительным, но не ThE MaGiCiAN oF ThE ELFS

if (!preg_match("??", $name)) {
   echo "Invalid name!";
}

надеюсь ты понимаешь!

Томаш

Недействителен:

MaGIciaN Of The ELFz
THomas anderson

Действительный:

Magician of the elfs
Magician Of the Elfs
Magician of The elfs
Thomas Anderson
Thomas anderson

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


person Tomasz    schedule 17.01.2010    source источник
comment
Вы действительно ищете только диапазон a-z? Обратите внимание, что класс символов [a-z], например, не содержит é.   -  person Bart Kiers    schedule 17.01.2010
comment
Вместо того, чтобы отклонять недопустимые имена, как насчет их исправления? Вы можете сделать $string=ucwords(strtolower($string)); чтобы недопустимый ввод соответствовал желаемому стилю.   -  person JAL    schedule 17.01.2010
comment
Символ пробела в допустимом примере не находится в диапазоне от a до z.   -  person mpez0    schedule 17.01.2010
comment
Из интереса, чего вы пытаетесь достичь? Я надеюсь, вы знаете, что не все имена пишутся с одной заглавной буквы для каждого слова. Например: Рональд Макдональд. Вы можете сделать предположение, но это все, что будет.   -  person John Carter    schedule 17.01.2010
comment
Просто примечание: если это решение против покемонов, ваше решение также запретит римские цифры (XXVII) и аббревиатуры (UNO). Может стоит тоже разрешить ВСЕ ЗАГЛАВНЫЕ.   -  person naivists    schedule 17.01.2010


Ответы (3)


Вы также можете описать символ с помощью его свойств символа Unicode:

/^\p{Lu}\p{Ll}*(?:\s+\p{Lu}\p{Ll}*)*$/

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

/^[\p{Lu}\p{Ll}]\p{Ll}*(?:\s+[\p{Lu}\p{Ll}]\p{Ll}*)*$/

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

person Gumbo    schedule 17.01.2010

'/^[A-Z][a-z]+( [A-Z][a-z]+)*$/'

Непроверенный, однако.

EDIT О, возможно, я неправильно понял ваш вопрос. Вышеприведенное предполагает минимальную длину слова, равную двум. Действительны ли "Джон А" или "Лошадь"? В этом случае: '/^[A-Z][a-z]*( [A-Z][a-z]*)*$/'.


Согласно обновленным требованиям:

'/^[A-Z][a-z]*( [A-Za-z][a-z]*)*$/'

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

person jensgram    schedule 17.01.2010
comment
Это должно делать свое дело. Обратите внимание, что PHP требует разделителей, которые я добавил. - person Bart Kiers; 17.01.2010
comment
Да, я забыл (и у нас была небольшая коллизия при редактировании). Теперь все должно быть в порядке. - person jensgram; 17.01.2010
comment
подождите, я бы хотел, чтобы Джон Хорс тоже был действительным - person Tomasz; 17.01.2010

Ух ты. \b, ребята.

if matches /\B[A-Z]/ then invalid

или, чтобы быть в курсе Unicode,

if matches /\B\p{Lu}/ then invalid

Вы можете сначала убедиться, что вся строка соответствует /^[\p{Lu}\p{Ll}\s]$/, чтобы не оставлять такие строки, как The (Magic) Elf, действительными.

person kennytm    schedule 17.01.2010
comment
Так вы предлагаете сделать это в два этапа? В этом случае я предпочитаю решения Gumbo и jensgram (всего один довольно интуитивный шаг). Если вы не выполните вторую проверку, пройдет не только The (Magic) Elf, но и такие строки, как ???????? или 11111111122222222 и т. д. - person Bart Kiers; 17.01.2010
comment
Это зависит от того, отфильтрованы ли уже входные данные, потому что пример спрашивающего не включает эти случаи. (И обновлено для дальнейшего упрощения теста.) - person kennytm; 17.01.2010
comment
На самом деле, ???????? и 1111111122222222 удовлетворяют основному требованию (не) иметь более 1 заглавной буквы в слове. В строке нет ни слов, ни заглавных букв, поэтому она проходит. - person kennytm; 17.01.2010
comment
Ничто в действительных примерах не говорит о том, что они действительны, но уверен: они могут быть. Хотя я бы не стал ставить на это деньги! :) - person Bart Kiers; 17.01.2010
comment
Ха-ха, вот почему точная спецификация стоит дорого :p - person kennytm; 17.01.2010