Из-за этого мы говорим, что операторы повторения (>+
, >*
, >?
, and >{}
) жадные, то есть они сначала захватывают, сколько могут, а потом идут назад. Если вы поместите вопрос после такого оператора (>+?
, >*?
, >??
, >{}?
), они превратятся в нежадных, и начнут находить самые маленькие из возможных вхождений.
И это то, что нам нужно. Заставив звёздочку находить совпадения в минимально возможном количестве символов строчки, мы поглощаем только один блок комментариев, и не более того.
>function stripComments(code) {
> return code.replace(/\/\/.*|\/\*[^]*?\*\//g, "");
>}
>console.log(stripComments("1 /* a */+/* b */ 1"));
>// → 1 + 1
Множество ошибок возникает при использовании жадных операторов вместо нежадных. При использовании оператора повтора сначала всегда рассматривайте вариант нежадного оператора.
Динамическое создание объектов RegExp
В некоторых случаях точный шаблон неизвестен во время написания кода. Например, вам надо будет искать имя пользователя в тексте, и заключать его в подчёркивания. Так как вы узнаете имя только после запуска программы, вы не можете использовать запись со слэшами.
Но вы можете построить строку и использовать конструктор >RegExp
. Вот пример:
>var name = "гарри";
>var text = "А у Гарри на лбу шрам.";
>var regexp = new RegExp("\\b(" + name + ")\\b", "gi");
>console.log(text.replace(regexp, "_$1_"));
>// → А у _Гарри_ на лбу шрам.
При создании границ слова приходится использовать двойные слэши, потому что мы пишем их в нормальной строке, а не в регулярке с прямыми слэшами. Второй аргумент для >RegExp
содержит опции для регулярок – в нашем случае >“gi”
, т. е. глобальный и регистронезависимый.
Но что, если имя будет >"dea+hl[]rd"
(если наш пользователь – кульхацкер)? В результате мы получим бессмысленную регулярку, которая не найдёт в строке совпадений.
Мы можем добавить обратных слэшей перед любым символом, который нам не нравится. Мы не можем добавлять обратные слэши перед буквами, потому что >\b
или >\n
– это спецсимволы. Но добавлять слэши перед любыми не алфавитно-цифровыми символами можно без проблем.
>var name = "dea+hl[]rd";
>var text = "Этот dea+hl[]rd всех достал.";
>var escaped = name.replace(/[^\w\s]/g, "\\$&");
>var regexp = new RegExp("\\b(" + escaped + ")\\b", "gi");
>console.log(text.replace(regexp, "_$1_"));
>// → Этот _dea+hl[]rd_ всех достал.
Метод >indexOf
нельзя использовать с регулярками. Зато есть метод >search
, который как раз ожидает регулярку. Как и >indexOf
, он возвращает индекс первого вхождения, или -1, если его не случилось.
>console.log(" word".search(/\S/));