Javascript regular expression problem with \b and international characters
I'm having a lot of problems with a simple regular expression match.
I have this string with accented characters (this is just an example) "Botó Entrepà Nadó Facebook! "
and I want to match words using words from another list.
This is a simplified version of my code. For example to match "Botó
"
var matchExpr = new RegExp ('\\b' + 'Botó' + '\\b','i');
"Botó Entrepà Nadó Facebook! ".match(matchExpr);
If I run it, it doesn't match "Botó
" as expected (Firefox, IE and Chrome).
I thought it was an error on my side. But here comes the fun...
If I modify the string like this "Botón Entrepà Nadó Facebook! "
(notice the "n
" after "Botó
") and I run the same code:
var matchExpr = new RegExp ('\\b' + 'Botó' + '\\b','i');
"Botón Entrepà Nadó Facebook! ".match(matchExpr);
It matches "Botó
"!!!!????? (at least in Firefox).
This does't make sense for me as "n
" is NOT a word boundary (that is matched by \b
).
If you try to match the whole word:
var matchExpr = new RegExp ('\\b' + 'Botón' + '\\b','i');
"Botón Entrepà Nadó Facebook! ".match(matchExpr);
It works.
To make it a little bit more weird, we add another accented letter at the end.
var matchExpr = new RegExp ('\\b' + 'Botóñ' + '\\b','i');
"Botóñ Entrepà Nadó Facebook! ".match(matchExpr);
If we try to match this, it matches nothing. BUT, if we try this
var matchExpr = new RegExp ('\\b' + 'Botóñ' + '\\b','i');
"Botóña Entrepà Nadó Facebook! ".match(matchExpr);
it matches "Botóñ
". Which is wrong.
If we try to match "Facebook" it开发者_JAVA百科 works as expected. If you try to match words with accents in the middle, it works as expected. But if you try to match words with an accent at the end, it fails.
What am I doing wrong? Is this the expected behaviour?
Unfortunately, the shorthand character classes in Javascript don't support unicode (or even high ASCII).
Take a look at the answers to this question: Javascript + Unicode. This article, linked in that question, JavaScript, Regex, and Unicode, says that \b
is defined by a word boundary, which is defined as:
→ Word character — The characters A-Z, a-z, 0-9, and _ only.
→ Word boundary — The position between a word character and non-word character.
So it will work for words with A-Z, a-z, 0-9, and _
at the end, but not with accented characters at the end.
From the ES3 spec:
The internal helper function IsWordChar takes an integer parameter e and performs the following:
- If e == –1 or e == InputLength, return false.
- Let c be the character Input[e].
If c is one of the sixty-three characters in the table below, return 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 _
Return false.
The "IsWordChar()" internal (possibly hypothetical) function is the basis of behavior for the "\b" assertion.
edit — it's no better in ES5.
精彩评论