Как я могу сделать регулярное выражение, которое учитывает символы с диакритическими знаками?

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

Граница слова ("\b") — это точка между двумя символами, у которой есть "\w" с одной стороны и "\W" с другой стороны (в любом порядке), при этом мнимые символы отсчитываются. начало и конец строки соответствуют "\W". Регулярное выражение AS3 для сопоставления слов с символами граничного типа в их

И с тех пор

\w соответствует любому буквенно-цифровому символу (символам слова), включая подчеркивание (сокращение от [a-zA-Z0-9_]). \W соответствует любым символам, не являющимся словами (сокращение от [^a-zA-Z0-9_]) http://www.javascriptkit.com/javatutors/redev2.shtml

явно акцентированные символы не учитываются. Это становится проблемой для таких слов, как Montréal. Если é считается границей слова, то al является двухбуквенным словом. Я попытался дать собственное определение границы слова, которое позволяло бы использовать символы с акцентом, но, поскольку граница слова — это даже не символы, я точно не знаю, как ее найти.

Любая помощь?

Вот соответствующий код JavaScript, который ищет userInput и находит двухбуквенные слова, используя регулярное выражение re_state:

var re_state = new RegExp("\\b([a-z]{2})[,]?\\b", "mi");
var match_state = re_state.exec(userInput);
document.getElementById("state").value = (match_state)?match_state[1]:"";

person Shawn    schedule 12.09.2010    source источник


Ответы (2)


Хотя регулярные выражения JavaScript в некоторых случаях распознают символы, отличные от ASCII (например, \s), они безнадежно неадекватны, когда речь идет о \w и \b. Если вы хотите, чтобы они работали с чем-либо помимо словесных символов ASCII, вам придется либо использовать другой язык, либо установить Стива Левитана. XRegExp с плагином Unicode.

Кстати, в вашем регулярном выражении есть ошибка. У вас есть \b после необязательной запятой, но она должна быть впереди:

"\\b([a-z]{2})\\b,?"

Я также удалил квадратные скобки; они вам понадобятся только в том случае, если запятая имеет особое значение в регулярных выражениях, чего нет. Но я подозреваю, что вам вообще не нужно сопоставлять запятую; \b должно быть достаточно, чтобы убедиться, что вы находитесь в конце слова. И если вам не нужна запятая, вам также не нужна группа захвата:

"\\b[a-z]{2}\\b"
person Alan Moore    schedule 12.09.2010
comment
@Alan Moore: В чем разница между использованием литерала и конструктора? Разница, которую я обнаружил, заключается в том, что если я использую конструктор, я могу добавить совпадения предыдущих регулярных выражений в свое регулярное выражение... например: var re_address = new RegExp(match_buildingNumber[0] + match_street[0] + match_city[0] + ?, ми); Такие вещи, которые, насколько мне известно, невозможны с литералом регулярного выражения... - person Shawn; 12.09.2010
comment
Хорошо, если у вас есть веская причина для использования конструктора, во что бы то ни стало используйте его. Я просто хотел убедиться, что вы знаете об опции regex-literal. - person Alan Moore; 12.09.2010
comment
@Алан Мур: хорошо, спасибо! Но мне все еще немного любопытно. В чем разница между ними? Почему следует предпочесть использование буквального, когда это возможно? Кроме того, я скачал XRegExp и плагин для юникода, но до сих пор не понимаю, как его использовать для того, что мне нужно. Я предполагаю, что где-то там будет Lm (измененная буква)? - person Shawn; 12.09.2010
comment
Просто с конструктором вы пишете регулярное выражение в виде строкового литерала, который имеет свой собственный набор правил экранирования. Например, если вы забыли экранировать обратную косую черту в своем регулярном выражении, вы будете искать слово, окруженное обратными пробелами, а не слово, окруженное границами слов. - person Alan Moore; 13.09.2010
comment
@Alan, я здесь размещен ответ, который показывает, как это сделать правильно. Вы должны создать объект сопоставления UCA, сила сравнения которого установлена ​​только как первичная. Вы можете сделать это на Perl, Python или Java, хотя только Perl поставляется с необходимыми классами в своем базовом дистрибутиве. Однако я не думаю, что в Javascript есть какие-либо соответствующие стандартам объекты, необходимые для этого. - person tchrist; 05.03.2011
comment
Предоставляет ли ES6 или любые другие обновления какие-либо исправления для этого? Я тоже сталкиваюсь с этим. \w останавливается на акцентированных буквенно-цифровых символах. К вашему сведению, я использую JS в браузере, поэтому альтернативных языков нет. - person 1.21 gigawatts; 08.11.2018
comment
Обновление. Я нашел сообщение, в котором определяется набор, который находит словесные символы с акцентами «конкретное регулярное выражение javascript для диакритических знаков с диакритическими знаками% 2326900132»> stackoverflow.com/questions/20690499/. Похоже, что [A-Za-zÀ-ÖØ-öø-ÿ0-9_] больше соответствует \w. Но в комментариях указано, что он соответствует латинским символам, но не кириллице или другим, поэтому применяются предостережения. - person 1.21 gigawatts; 08.11.2018

Вы настроили JavaScript для использования не-ASCII? Вот страница, предлагающая настроить JavaScript для использования UTF-8: http://blogs.oracle.com/shankar/entry/how_to_handle_utf_8

В нем говорится:

добавьте атрибут charset (charset="utf-8") в теги скрипта на родительской странице:

script type="text/javascript" src="[path]/myscript.js"  charset="utf-8"
person Beel    schedule 12.09.2010
comment
Да, атрибута type нет даже в HTML5, поскольку он не поддерживается браузерами, это ошибка, допущенная людьми при интерпретации спецификации. Метатег charset работает, но charset в ссылках не является реальной вещью. - person Rich Bradshaw; 12.09.2010
comment
@Rich Брэдшоу: у меня есть ‹мета http-equiv=content-type content=text/html; charset=utf-8 /› в моей голове. Это то, что вы имели ввиду? - person Shawn; 12.09.2010
comment
Это тоже неправильно. Речевые метки, добавляемые людьми для XHTML, должны определять два атрибута: содержимое и кодировку, но народная мудрость почему-то ставит их в одни и те же речевые метки с точкой с запятой! Однако браузеры анализируют это и заставляют его работать. Проверьте версию HTML5, чтобы найти лучший/соответствующий способ сделать это. Charset на js и CSS никогда не работал, и добавлять его бессмысленно. - person Rich Bradshaw; 13.09.2010