Регулярное выражение Javascript с группой без захвата в качестве двух альтернатив - PullRequest
0 голосов
/ 02 июля 2018

Я хотел бы создать регулярное выражение, которое позволяет вводить значения, такие как Name и Surname. Но у меня есть некоторые ограничения:

  • Прописная первая буква (только одна), а затем другие маленькие буквы
  • После предыдущего пользователь может использовать ', - или (пробел) и после этого применять то же правило, что и в первой точке

Я почти достиг этого, но что-то все еще не работает должным образом. Вот мое творение:

/^[A-ZÀ-ž]{1}[a-zà-ž]+[\s\'-]{0,1}(?:(?=[\s\'-]{0,1})[A-ZÀ-ž]{1}[a-zà-ž]+|(?=[\s\'-]{0,1})[a-zà-ž]+)$/i

Я хочу использовать его в Javascript с функцией .test(value). К сожалению, он также принимает это:

  • Test
  • Test -
  • Test-
  • test
  • Test
  • Test-test
  • TTest
  • Test'test

То, что я хочу, чтобы меня приняли и разрешили, это:

  • Test
  • Test-Test
  • Test Test
  • Test'Test

Понятия не имею, что я делаю неправильно и как это исправить ... Чего мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

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

Вот диапазоны, которые вам нужны:

Прописные (основной европейский)

  • Базовая латиница - прописные буквы латинского алфавита: [A-Z]
  • Дополнение по латинице 1 - Буквы - Прописные буквы: [À-ÖØ-Þ]
  • Расширенная латиница A - Европейская латиница - Прописные буквы: [ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJijĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒœŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽ]

Строчные (базовый европейский)

  • Базовая латиница - строчные латинские буквы: [a-z]
  • Latin 1 Дополнение - Буквенные символы - строчные буквы: [ß-öø-ÿ]
  • Латинская расширенная A - Европейская латиница - Строчные буквы: [žſāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľŀłńņňŋōŏőŕŗřśŝşšţťŧũūŭůűųŵŷźż]

Нужный вам шаблон:

/^[UPPER][lower]+(?:[\s'-][UPPER][lower]+)*$/

, где UPPER и lower - диапазоны / наборы прописных и строчных букв.

Итак, давайте построим шаблон.

var upper = '[A-ZÀ-ÖØ-ÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJijĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒœŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽ]';
var lower = '[a-zß-öø-ÿžſāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľŀłńņňŋōŏőŕŗřśŝşšţťŧũūŭůűųŵŷźż]';
var rx = new RegExp("^" + upper + lower + "+(?:[\\s'-]" + upper + lower + "+)*$");
// Let's test
var tests = ['Test ','Test - ','Test-',' test','Test-test','TTest','Test\'test','Test','Test-Test','Test Test','Test\'Test', 'Łóźćż\'żłóźćęą'];
for (var s of tests) {
  console.log(s, '=>', rx.test(s))
}

ПРИМЕЧАНИЕ есть еще буквы, которые можно использовать на европейских языках. Для получения дополнительной информации см. Unicode Utilities для справки.

ПРИМЕЧАНИЕ 2 : если вы планируете поддерживать только Chrome и другие совместимые с ECMAScript 2018 браузеры, вы можете использовать

console.log(  // ONLY WORKS IN ECMASCRIPT 2018 COMPATIBLE JS ENVIRONMENTS
  /^\p{Lu}\p{Ll}+(?:[\s'-]\p{Lu}\p{Ll}+)*$/u.test("Test'Ťĕśţ")
);

Java-определение:

String pattern = "(?U)^\\p{Lu}\\p{Ll}+(?:[\\s'-]\\p{Lu}\\p{Ll}+)*$";

Если вы используете его в методе Java matches(), удалите ^ и $, поскольку они там избыточны.

0 голосов
/ 02 июля 2018

Ваше регулярное выражение в некоторых местах "слишком многословно", например ::1001

  • {1} не нужен вообще. Число повторений по умолчанию равно 1.
  • {0,1} можно записать короче как ?.
  • \ перед ' не требуется.

Вы также использовали два случая (?= ... ) - положительных взглядов , которые здесь совершенно не нужны.

Регулярное выражение, предложенное Wiktor , почти нормально, но я бы изменил последнее * на ?, потому что вы упомянули только одну необязательную фамилию (не так много).

Итак, мое предложение:

^[A-ZÀ-Ž][a-zà-ž]+(?:[\s'-][A-ZÀ-Ž][a-zà-ž]+)?$

Описание:

  • ^ - Начало исходной строки.
  • [A-ZÀ-Ž] - заглавная буква (начало названия).
  • [a-zà-ž]+ - последовательность строчных букв (остальная часть имени).
  • (?: - группа без захвата, необходимая из-за ? после нее.
    • [\s'-] - Либо белый символ, либо апостроф, либо минус (разделитель между именем и фамилией).
    • [A-ZÀ-Ž][a-zà-ž]+ - Фамилия - так же, как и имя.
  • )? - Конец группы без захвата, необязательно. Вместо ?, Виктор предложил *, разрешив много фамилий.
  • $ - конец исходной строки.

Таким образом, группа без захвата устанавливается как контейнер для:

  • разделитель,
  • фамилия.

Необязательно (?), как фамилия (вместе с предыдущим разделителем) может отсутствовать.

Может быть \s следует заменить только пробелом, потому что \s соответствует также Tab или '\n', и я думаю, эти символы не должны быть разрешены в качестве разделителя.

...