Проблема регулярного выражения 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.