\B: the non word boundary and what it is good for
\B asserts the exact opposite of \b: that the two characters either side of the current position are either both word characters or both not. It is the assertion for matching inside a word.
At a glance
- Syntax
- \B
- Type
- zero width assertion, it consumes nothing
- Succeeds when
- both sides are word characters, or neither side is
- At a string edge
- fails next to a word character, succeeds otherwise
- Positive form
- \b
- Typical use
- finding a substring only when it sits inside a longer word
In detail
The most direct use is an inside a word search. Wrapping a term in \B on both sides finds it only when it is embedded: /\Bcat\B/ finds the cat in scatter and skips both the standalone word cat and the plural cats, because each of those has a real boundary on at least one side.
It is also the assertion behind the thousands separator idiom. In /\B(?=(\d{3})+(?!\d))/g the \B stops a comma being inserted at the very start of the number, since position zero next to a digit is a boundary. Remove it and the same pattern produces a leading comma.
Because \B succeeds when neither side is a word character, it also matches in runs of punctuation. A hyphen in the middle of a run of hyphens has \B on both sides, while the outer ones do not, which is occasionally a neat way to find the interior of a run of separators.
The thing to remember is that \B is a negation, not a different kind of boundary. It fails wherever \b succeeds and succeeds everywhere else, including at both string edges when the adjacent character is not a word character. Reading it as almost a boundary produces patterns that behave the opposite way to their author's intent.
Examples
"cat scatter cats".match(/\Bcat\B/g); // ["cat"]Only the occurrence inside scatter has a non boundary on both sides.
"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, ","); // "1,234,567"
"x1 2 34".match(/\B\d/g); // ["1", "4"]
"a---b".match(/\B-\B/g); // ["-"], only the middle hyphenThings that catch people out
- \B is not a weaker \b. It is the exact negation, so a pattern that swaps one for the other matches a disjoint set of positions rather than a wider one.
- /\Ba/ can never match a string that starts with a, because position zero next to a word character is always a boundary.
- \B succeeds between two punctuation characters, so a pattern relying on it to mean inside a word also fires in the middle of a run of symbols.
Try it: Regex Tester
Type a pattern and a test string, watch every match highlight as you go, read a plain English breakdown of each token, and check the numbered and named groups it captured.
Regex Tester
LOCAL · Browser-OnlyTest and debug regular expressions with live matching and highlights
Related Regex syntax
All regex syntax →\b: word boundaries, underscores and accented letters
\b is a zero width assertion defined entirely in terms of \w, which is why user_name has no internal boundary and café has none at its end.
\w: the word character class, underscore included
\w is exactly [A-Za-z0-9_] in JavaScript. That includes the underscore and excludes every accented letter, which is where most \w bugs come from.
The $ anchor: end of string, and the trailing newline question
Where $ matches in JavaScript, why it refuses to match before a trailing newline when Python and Ruby allow it, and how to write a literal dollar sign.
The * quantifier: zero or more, including nothing at all
The star quantifier succeeds even when it matches nothing, which is why a global match against it returns an empty string at almost every position.
The + quantifier: one or more, and when to prefer it
The plus quantifier requires at least one repetition, which is what makes it the right default for validation where the star quietly accepts nothing.
The ? quantifier: optional, and its two other jobs
A question mark after a token makes it optional. The same character also marks a lazy quantifier and opens a special group, which is why patterns look dense.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links