Пример № 1 — последовательность одинаковых символов встречается один раз в строке
Есть строка:
var stroka = "Магазиииииииииин"
В этой строке очень часто записана буква «и» — одна следом за другой. Как удалить «лишние» буквы «и» и оставить только одну?
Воспользуемся квантификатором «+» и отберём последовательность повторяющихся букв «и»
stroka.match(/и+/)
Нам вернётся такой объект:
["ииииииииии", index: 5, input: "Магазиииииииииин", groups: undefined]
Знак плюс «+» означает сопоставление текущего элемента с предшествующим элементом один или более раз. Эквивалентен квантификатору {1,}
Можем заменить:
var stroka2 = stroka.replaceAll(stroka.match(/и+/), "и")
Получим:
stroka2 "Магазин"
Пример № 2 — последовательность одинаковых символов встречается несколько раз в строке
Есть строка:
var stroka = "Маагаааааазин"
Как удалить «лишние» буквы «а» из двух последовательностей и оставить только одну?
var stroka2 = stroka.replace(/а+/g,'а') или var stroka2 = stroka.replace(/а+(?=а)/g,'')
Такая команда удалит все дубли букв «а» во всех последовательностях строки.
Удаление через Дизъюнкцию:
Удаление через Утверждение:
Как это работает?
Конструктор регулярных выражений (RegExp) применяет следующую грамматику к входному шаблону String. Ошибка возникает, если грамматика не может интерпретировать String как расширение Pattern.
В паттерне (Pattern) можно использовать Утверждения (Assertion):
В нашем случае мы использовали конструкцию Утверждения ( ? = Disjunction[?U, ?N] )
То есть мы сопоставляем то, что находится слева от круглой скобки с тем, что находится внутри круглых скобок. Дизъюнкция (Disjunction) — это разъединение, разделение. Нашим символом разделения будет являться буква «а«. В качестве сопоставления мы указали на букву «а» перед Утверждением (слева от круглой скобки). То есть, мы имеем как-бы две буквы «а». Цветами отмечены для лучшего понимания:
/а+(?=а)/g
Мы добавили квантификатор «+» к сопоставляемой букве «а«, чтобы отловить множественные появления последовательностей буквы «а» в строке. Внутри утверждения мы ищем границы, где буква «а» соседствует с такой же буквой «а» (символьное равенство).
Затем мы использовали флаг «g» для регулярных выражений, который говорит нам о том, что условие Утверждения будет проверено «глобально» по всей строке. То есть при помощи флага «g» мы отловим все возможные варианты последовательностей букв с квантификатором «а+«. В этом случае флаг «g» выходит за границу регулярного выражения / / и размещается справа.
Когда мы отловили все варианты последовательностей буквы «а» (где «а» соседствует с «а«) по всей строке, то теперь можем воспользоваться методом замены replace() для объектов-прототипов String. Искомые значения (первый параметр) мы будем заменять на пустую строку (второй параметр). Почему на пустую строку, а не на букву «а«. Потому что Утверждение находит только границы между одной последней буквы «а» в последовательности возможных.
Примеры: а|a, аа|a, ааа|a, и так далее.
Когда начнётся замена, тогда все вариации (что слева от Границы Утверждения) будут заменены на пустую строку, а значит останется только один символ «а«, который по факту является последним в цепочке однотипных последовательностей. Напомню, что сопоставление ведётся по левой стороне Утверждения — слева у нас «а+«.
В этом Утверждении соответствие символов велось по «началу» последовательности букв «а».
Но мы можем решить задачу другой конструкцией регулярных выражений и вести соответствие последовательности по «концу»:
var stroka = "Маагаааааазин" var stroka2 = stroka.replace(/(?<=а)а+/g,'')
Информационные ссылки
JavaScript | Флаги регулярных выражений
ECMAScript | Квантификатор (Quantifier) | Регулярные выражения (Regular Expression)
JavaScript | Квантификаторы *(звёздочка), +(плюс), ?(вопрос)
JavaScript | Квантификатор {} фигурные скобки в регулярных выражениях
Стандарт ECMAScript — Раздел «22.1.3.11 String.prototype.match ( regexp )» — https://tc39.es/ecma262/#sec-string.prototype.match
Стандарт ECMAScript — Раздел «22.1.3.17 String.prototype.replace ( searchValue, replaceValue )» — https://tc39.es/ecma262/#sec-string.prototype.replace
Стандарт ECMAScript — Раздел «22.2.2.5.1 RepeatMatcher ( m, min, max, greedy, x, c, parenIndex, parenCount )» — https://tc39.es/ecma262/#sec-runtime-semantics-repeatmatcher-abstract-operation
Стандарт ECMAScript — Раздел «22.2 RegExp (Regular Expression) Objects» — https://tc39.es/ecma262/#sec-regexp-regular-expression-objects