Конкретное Javascript Regex для акцентированных символов (диакритика)
Я посмотрел на Qaru (замену символов.. eh, как JavaScript не соответствует стандарту Unicode относительно RegExp и т.д.) и на самом деле не нашли конкретного ответа на вопрос:
How can JavaScript match for accented characters (those with diacritical marks)?
Я заставляю поле в пользовательском интерфейсе соответствовать формату: last_name, first_name
(последнее [запятое пространство]), и я хочу предоставить поддержку диакритики, но, очевидно, в JavaScript это немного сложнее, чем другие языки/платформы.
Это была моя оригинальная версия, пока я не захотел добавить диакритическую поддержку:
/^[a-zA-Z]+,\s[a-zA-Z]+$/
В настоящее время я обсуждаю один из трех способов добавления поддержки, все из которых я тестировал и работал (по крайней мере, в некоторой степени, я не знаю, что такое "степень" второго подхода). Вот они:
Явное перечисление всех акцентированных символов, которые я хотел бы принять как действительные (хромые и слишком сложные):
var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇߨøÅ寿œ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇߨøÅ寿œ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇߨøÅ寿œ]+$/
- Это правильно соответствует последнему/первому имени с любым из поддерживаемых акцентированных символов в
accentedCharacters
.
Мой другой подход состоял в том, чтобы использовать класс символов .
, чтобы иметь более простое выражение:
var regex = /^.+,\s.+$/;
- Это будет соответствовать примерно чем угодно, по крайней мере, в форме:
something, something
. Это хорошо, я полагаю...
Последний подход, который я просто нашел, может быть проще...
/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
- Он соответствует диапазону символов юникода - проверен и работает, хотя я не пробовал ничего сумасшедшего, просто нормальный материал, который я вижу в нашем языковом отделе для имен членов факультета.
Вот мои проблемы:
- Первое решение слишком ограничено и небрежно и запутанно. Его нужно было бы изменить, если бы я забыл характер или два, и это просто не очень практично.
- Второе решение лучше, кратким, но, вероятно, оно намного больше, чем на самом деле. Я не мог найти никакой реальной документации о том, что именно соответствует
.
, просто обобщение "любого символа, кроме символа новой строки" (из таблицы на MDN).
-
Третье решение кажется самым точным, но есть ли какие-либо ошибки? Я не очень хорошо знаком с Unicode, по крайней мере на практике, но смотрю таблицу кодов/продолжение этой таблицы, \u00C0-\u017F
кажется довольно прочным, по крайней мере, для ожидаемого ввода.
- Факультет не будет подавать формы с их именами на своем родном языке (например, на арабском, китайском, японском и т.д.), поэтому мне не нужно беспокоиться о символах с символами, отличными от латиницы
Итак, реальный вопрос (ы): Какой из этих трех подходов наиболее подходит для задачи? Или есть лучшие решения?
Ответы
Ответ 1
Какой из этих трех подходов наиболее подходит для задачи?
Зависит от задачи:-) Чтобы точно соответствовать всем латинским символам и их акцентированным версиям, диапазоны Unicode, вероятно, обеспечивают лучшее решение. Они могут быть расширены до всех символов без пробелов, которые могут быть выполнены с использованием класса символов \S
.
Я заставляю поле в пользовательском интерфейсе соответствовать формату: last_name, first_name
(последнее [запятое пространство])
Самая основная проблема, которую я вижу здесь, - это не диакритики, а пробелы. Есть несколько имен, которые состоят из нескольких слов, например. для названий. Поэтому вы должны пойти с самым общим, то есть разрешить все, кроме запятой, которая отличает сначала от фамилии:
/[^,]+,\s[^,]+/
Но ваше второе решение с классом символов .
так же хорошо, вам может потребоваться только несколько комматиков.
Ответ 2
Более простой способ принять все акценты заключается в следующем:
[A-zÀ-ú] // accepts lowercase and uppercase characters
[A-zÀ-ÿ] // as above but including letters with an umlaut (includes [ ] ^ \ × ÷)
[A-Za-zÀ-ÿ] // as above but not including [ ] ^ \
[A-Za-zÀ-ÖØ-öø-ÿ] // as above but not including [ ] ^ \ × ÷
См. Https://unicode-table.com/en/ для символов, перечисленных в числовом порядке.
Ответ 3
\u00C0-\u017F
латинского диапазона \u00C0-\u017F
было недостаточно для моей базы данных имен, поэтому я расширил выражение до
[a-zA-Z\u00C0-\u024F]
[a-zA-Z\u00C0-\u024F\u1E00-\u1EFF] // includes even more Latin chars
Я добавил эти блоки кода (\u00C0-\u024F
включает три смежных блока одновременно):
Обратите внимание, что \u00C0-\u00FF
на самом деле является лишь частью дополнения Latin-1. Этот диапазон пропускает непечатаемые управляющие сигналы и все символы, кроме неуклюже помещенного умножения × \u00D7
и деления ÷ \u00F7
.
-
\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF
может заменить \u00C0-\u00FF
для исключения × ÷
Если вам нужно больше кодовых точек, вы можете найти больше диапазонов в Википедии. Список символов Юникода. Например, вы также можете добавить Latin Extended-C, D и E, но я не учел их, потому что сейчас их интересуют только историки, а наборы D и E даже неправильно отображаются в моем браузере.
Оригинальное регулярное выражение, остановившееся на \u017F
расторгалось под именем "olenol". Согласно FontSpace Unicode Analyzer, первым символом является \u0218
, LATIN CAPITAL LETTER S с запятой ниже. (Да, это обычно пишется с помощью cedilla-S \u015E
, "Шенол". Но я не лечу в Турцию, чтобы сказать ему: "Вы пишете свое имя неправильно!")
Ответ 4
Библиотека XRegExp имеет плагин с именем Unicode, который помогает решать такие задачи.
<script src="xregexp.js"></script>
<script src="addons/unicode/unicode-base.js"></script>
<script>
var unicodeWord = XRegExp("^\\p{L}+$");
unicodeWord.test("Русский"); // true
unicodeWord.test("日本語"); // true
unicodeWord.test("العربية"); // true
</script>
Он упомянул в комментариях к вопросу, но его легко пропустить. Я заметил это только после того, как я представил этот ответ.
Ответ 5
Как насчет этого?
/^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/
Ответ 6
Как насчет этого?
^([a-zA-Z]|[à-ú]|[À-Ú])+$
Он будет соответствовать каждому слову с акцентированными символами или нет.
Ответ 7
из этой вики: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin
для латинских букв я использую
/^[A-zÀ-ÖØ-öø-ÿ]+$/
избегает дефисов и специальных символов