Проблема регулярного выражения Javascript с \b и международными символами
У меня много проблем с простым совпадением регулярных выражений.
У меня есть эта строка с акцентированными символами (это всего лишь пример) "Botó Entrepà Nadó Facebook! "
, и я хочу совместить слова, используя слова из другого списка.
Это упрощенная версия моего кода. Например, чтобы соответствовать "Botó
"
var matchExpr = new RegExp ('\\b' + 'Botó' + '\\b','i');
"Botó Entrepà Nadó Facebook! ".match(matchExpr);
Если я запустил его, он не соответствует "Botó
", как ожидалось (Firefox, IE и Chrome).
Я думал, что это ошибка на моей стороне. Но здесь приходит весело...
Если я изменяю строку, подобную этой "Botón Entrepà Nadó Facebook! "
(обратите внимание на "n
" после "Botó
" ), и я запускаю тот же код:
var matchExpr = new RegExp ('\\b' + 'Botó' + '\\b','i');
"Botón Entrepà Nadó Facebook! ".match(matchExpr);
Он соответствует "Botó
"!!!!????? (по крайней мере, в Firefox).
Для меня это не имеет значения, так как "n
" не является границей слов (это соответствует \b
).
Если вы попытаетесь совместить все слово:
var matchExpr = new RegExp ('\\b' + 'Botón' + '\\b','i');
"Botón Entrepà Nadó Facebook! ".match(matchExpr);
Он работает.
Чтобы сделать его немного более странным, добавим еще одну акцентированную букву в конце.
var matchExpr = new RegExp ('\\b' + 'Botóñ' + '\\b','i');
"Botóñ Entrepà Nadó Facebook! ".match(matchExpr);
Если мы попытаемся сопоставить это, оно ничего не соответствует. НО, если мы попробуем это
var matchExpr = new RegExp ('\\b' + 'Botóñ' + '\\b','i');
"Botóña Entrepà Nadó Facebook! ".match(matchExpr);
он соответствует "Botóñ
". Это неправильно.
Если мы попытаемся сопоставить "Facebook", он работает так, как ожидалось.
Если вы пытаетесь совместить слова с акцентами в середине, он работает так, как ожидалось.
Но если вы попытаетесь совместить слова с акцентом в конце, это не сработает.
Что я делаю неправильно? Это ожидаемое поведение?
Ответы
Ответ 1
К сожалению, классы сокращенных символов в Javascript не поддерживают unicode (или даже высокий ASCII).
Взгляните на ответы на этот вопрос: Javascript + Unicode. В этой статье, связанной с этим вопросом, JavaScript, Regex и Unicode, говорится, что \b
определяется границей слов, которая определена как:
→ Символ Word - символы A-Z, a-z, 0-9 и _ только.
→ граница слова - позиция между символом слова и не-слов.
Таким образом, он будет работать для слов с A-Z, a-z, 0-9, and _
в конце, но не с акцентированными символами в конце.
Ответ 2
Из спецификации ES3:
Внутренняя вспомогательная функция IsWordChar принимает целочисленный параметр e и выполняет следующее:
- Если e == -1 или e == InputLength, верните false.
- Пусть c - символ Input [e].
-
Если c является одним из шестидесяти трех символов в таблице ниже, верните true.
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 _
-
Возвращает false.
Внутренняя (возможно гипотетическая) функция IsWordChar() является основой поведения для утверждения "\ b".
edit — это не лучше в ES5.