Поддержка русских букв в границах слов в регулярных выражениях JavaScript

Написал небольшой код:

var a = "температура, температуры, температуров, температур, температурой"; /*текст*/
var b = "температур"; /*что заменяем*/
a.replace(new RegExp(b, 'g'),"осадок"); /*на что заменяем*/

В результате получил такой ответ:

осадока, осадокы, осадоков, осадок, осадокой

Как делать так, чтобы заменились только то, что мы указали?


Ответы (1 шт):

Автор решения: Wiktor Stribiżew

Так как границы слова \b работают только с буквами из набора ASCII, необходимо использовать "пользовательскую реализацию".

Например, используя новый ECMAScript 2018, можно реализовать границу слова с помощью блоков предварительного просмотра (?<![\p{L}\p{M}\p{N}_]) и (?![\p{L}\p{M}\p{N}_]) и флага-модификатора u.

Следующий пример кода работает в Chrome, Opera, Node.js, но, к сожалению, не сработает в FireFox и IE:

let a = "температура, температуры, температуров, температур, температурой"; /*текст*/
const b = "температур";
const reg = new RegExp(String.raw`(?<![\p{L}\p{M}\p{N}_])${b}(?![\p{L}\p{M}\p{N}_])`, 'gu');
console.log(a.replace(reg,"осадок")); 

Можно использовать упрощённый подход: "добавить" в \w (=[a-zA-Z0-9_]) русские буквы => [a-zA-Z0-9а-яА-ЯёЁ_], тогда получится следующий пример, который сработает во всех браузерах и средах:

var a = "температура, температуры, температуров, температур, температурой"; /*текст*/
var b = "температур";
var reg = new RegExp('(^|[^a-zA-Z0-9а-яА-ЯёЁ_])' + b + '(?![a-zA-Z0-9а-яА-ЯёЁ_])', 'g');
console.log(a.replace(reg,"$1осадок"));

→ Ссылка