Q:

Regex not replacing all occurrences

I'm trying to replace all occurrences of a Regex search & replace using the following code and for some reason it only replaces the first occurrence:

var userContent = '<div class="header"><!--Start Main Menu--><ul class="main-menu"> <li><a href="/">Home</a> </li> <li><a href="/">About</a> </li> <li><a href="/">Portfolio</a> </li> <li><a href="/">Contact</a> </li> </ul><!--End Main Menu--></div><div class="footer"><!--Start Main Menu--><ul class="main-menu"> <li><a href="/">Home</a> </li> <li><a href="/">About</a> </li> <li><a href="/">Portfolio</a> </li> <li><a href="/">Contact</a> </li> </ul><!--End Main Menu--></div>';

var menuItems = "<li><a href='/'>Home</a></li><li><a href='/about'>About</a></li><li><a href='/portfolio'>Portfolio</a></li><li><a href='/contact'>Contact</a></li>";

var quote = function(str) {
    return str.replace(/([.?*+^$[\]/(){}|-])/g, "\\$1");
};

var re = new RegExp(quote('<!--Start Main Menu-->') + "[^]+" + quote('<!--End Main Menu-->'), 'g');
userContent = userContent.replace(re, '<!--Start Main Menu--><ul class="main-menu">' + menuItems + '</ul><!--End Main Menu-->');

console.log(userContent);

I can't seem to figure out why, I've stated in quote /g and I've tried adding /g to userContent.replace but it just doesn't seem to like it.
Fiddle: https://jsfiddle.net/xqt3kj7r/

A:

You are matching greedy, and so the regular expression ate up all the chars within the first occurrence of 'Start Main Menu' and the last occurrence of 'End Main Menu'.
What would be required is a non-greedy match. Try this:

var userContent = '<div class="header"><!--Start Main Menu--><ul class="main-menu"> <li><a href="/">Home</a> </li> <li><a href="/">About</a> </li> <li><a href="/">Portfolio</a> </li> <li><a href="/">Contact</a> </li> </ul><!--End Main Menu--></div><div class="footer"><!--Start Main Menu--><ul class="main-menu"> <li><a href="/">Home</a> </li> <li><a href="/">About</a> </li> <li><a href="/">Portfolio</a> </li> <li><a href="/">Contact</a> </li> </ul><!--End Main Menu--></div>';

var menuItems = "<li><a href='/'>Home</a></li><li><a href='/about'>About</a></li><li><a href='/portfolio'>Portfolio</a></li><li><a href='/contact'>Contact</a></li>";

var quote = function(str) {
    return str.replace(/([.?*+^$[\]/(){}|-])/g, "\\$1");
};

var re = new RegExp(quote('<!--Start Main Menu-->') + "[^]*?" + quote('<!--End Main Menu-->'), 'g');
userContent = userContent.replace(re, '<!--Start Main Menu--><ul class="main-menu">' + menuItems + '</ul><!--End Main Menu-->');

console.log(userContent);

Note how the RE changed from + to *?. I don't find it a good practice to approach this with a regular expression, but this is just to show you how it could have worked.

