User:Gerbrant/edit/multiReplace.js

try {	"A".replace(/A|(B)/, function(a, b)	{		if(b != undefined) throw false;		return a;	}); } catch(e) {	(function(m)	{		alert(m);		throw new Error(m);	})("The script Gerbrant.edit.multiReplace cannot be used because your browser's implementation of String.prototype.replace is buggy. More specifically, it doesn't handle non-participating capturing groups correctly."); }

module("Gerbrant.edit.multiReplace", function {

patterns = []; handlers = []; indices = []; var j = 1;

this.add = function(p, h) { var n = p.match(/\((?!\?)/g);	if(n) n = n.length + j;	else n = j;	patterns.push(p.replace(/\\(\d+)/, function(a, b)	{		return "\\" + (+b + n - 1);	}));	handlers.push(h);	indices.push([j, ++n]);	j = n; }

//equivalent aan a.slice(b, e), maar dat werkt niet voor arguments function sliceArg(a, b, e) { n = []; while(b < e) n.push(a[b++]); return n; }

this.handler = function(a) {	var i, idx; for(i in indices) {		idx = indices[i]; if(arguments[idx[0]] != undefined) try {				return handlers[i].apply(a, sliceArg(arguments, idx[0], idx[1])); }			catch(e) {				alert(e.message + "\n\n" + handlers[i]); return a;			} }	throw "Failed sanity check."; }

this.getRE = function {	return new RegExp("(" + patterns.join(")|(") + ")", "g") };

this.replace = function(t) {	return t.replace(this.getRE, this.handler); };

});