Replace content that is between to comments

55 Views Asked by At

I would like to replace the content that is between two comments like

/**** Useless CSS ****/
.my-class{
 margin: 12px;
}

/* Several Lines after including other comments **/

/**** END Useless CSS ****/

.other {
 padding: 12px;
}
/* Hello */

So far I have:

[\/* Useless CSS \*\/](.|[\r\n])*?END Useless CSS \*\*\*\*\/?

But this doesn't work. I got an error in Regex101: Catastrophic backtracking

3

There are 3 best solutions below

0
ctwheels On BEST ANSWER

Part of your issue is the first part of your regex. You're using [\/* Useless CSS \*\/], a character class, which means any character in this set. In other words any of the following characters (after removing duplicate letters): /* UselCS. That's definitely not your intention, but that's what it's doing. The code below removes the character class from the pattern so that it matches /**** Useless CSS ****/ explicitly.

The second change is turning (.|[\r\n])*? into [\s\S]*?. There's no need to have regex check against two options each time. If it's a set of characters, just add them to the same character class. [\s\S] is a way of representing any character (including the newline character). Another way (works in JavaScript, but not many other regex engines) is to use [^].

The third change was changing \*\*\*\* to \*{4}. Not only is this shorter and easier to understand, it also improves performance because the regex engine doesn't need to go token by token \*, then \*, then \*, etc. It's told to match * four times, so it does it in one go instead of 4. This means that \*\*\*\* takes four steps while \*{4} only takes one.

You may also append \s* to the end to remove additional whitespace.

\/\*{4} Useless CSS \*{4}\/[\s\S]*?\/\*{4} END Useless CSS \*{4}\/

var s = `/**** Useless CSS ****/
.my-class{
 margin: 12px;
}

/* Several Lines after including other comments **/

/**** END Useless CSS ****/

.other {
 padding: 12px;
}
/* Hello */`
var r = /\/\*{4} Useless CSS \*{4}\/[\s\S]*?\/\*{4} END Useless CSS \*{4}\//gi

console.log(s.replace(r, ''))

0
revo On

Your regex almost works but you should consider some changes represented as below:

(\/\*+ Useless CSS \*+\/)(.|[\r\n])*?END Useless CSS \*\*\*\*\/
^  ^ ^               ^  ^

Explanations:

  • Changing [...] to (...). Former defines a character class, latter a group.
  • Escaping * to express a literal character which otherwise works as a regex quantifier

  • Quantifying \* with + to match * characters in a sequence.

Live demo

also (.|[\r\n]) which is supposed to match any character up to a point is a bad alternative for [\s\S] or [^] (in JS). Besides, I'd add \s* at the end of pattern to match left whitespaces:

\/\*+ Useless CSS \*+\/[^]*?END Useless CSS \*+\/\s*
                                                 ^^^

Live demo

0
Prinzhorn On

Just because you could use regular expressions doesn't mean you have to use regular expressions.

let css = `
.boat {
 float: left;
}

/**** Useless CSS ****/
.my-class{
 margin: 12px;
}

/* Several Lines after including other comments **/

/**** END Useless CSS ****/

.other {
 padding: 12px;
}
/* Hello */`;

const START_DELIMITER = '/**** Useless CSS ****/';
const END_DELIMITER = '/**** END Useless CSS ****/';

const left = css.slice(0, css.indexOf(START_DELIMITER));
const right = css.slice(css.indexOf(END_DELIMITER) + END_DELIMITER.length);

console.log(left + 'NEW STUFF' + right);