javascript - Changing the RegExp flags -
so wrote myself function able count number of occurances of substring in string:
string.prototype.numberof = function(needle) { var num = 0, lastindex = 0; if(typeof needle === "string" || needle instanceof string) { while((lastindex = this.indexof(needle, lastindex) + 1) > 0) {num++;} return num; } else if(needle instanceof regexp) { // needle.global = true; return this.match(needle).length; } return 0; };
the method performs rather , both regexp , string based searches quite comparable execution time (both ~2ms on entire vast ray bradbury's "451 fahrenheit" searching "the"s).
what sort of bothers me, though, impossibility of changing flag of supplied regexp instance. there no point in calling string.prototype.match in function without global flag of supplied regular expression set true, note first occurance then. set flag manually on each regexp passed function, i'd prefer being able clone , manipulate supplied regular expression's flags.
astonishingly enough, i'm not permitted regexp.prototype.global flag (more precisely flags) appear read-only. thence commented-out line 8.
so question is: is there nice way of changing flags of regexp object?
i don't wanna stuff this:
if(!expression.global) expression = eval(expression.tostring() + "g");
some implementations might not event support regexp.prototype.tostring , inherit object.prototype, or different formatting entirely. , seems bad coding practice begin with.
first, current code not work correctly when needle
regex not match. i.e. following line:
return this.match(needle).length;
the match
method returns null
when there no match. javascript error generated when length
property of null
(unsuccessfully) accessed. fixed so:
var m = this.match(needle); return m ? m.length : 0;
now problem @ hand. correct when global
, ignorecase
, multiline
read properties. option create new regexp. done since regex source string stored in re.source
property. here tested modified version of function corrects problem above , creates new regexp object when needle
not have global
flag set:
string.prototype.numberof = function(needle) { var num = 0, lastindex = 0; if (typeof needle === "string" || needle instanceof string) { while((lastindex = this.indexof(needle, lastindex) + 1) > 0) {num++;} return num; } else if(needle instanceof regexp) { if (!needle.global) { // if global flag not set, create new one. var flags = "g"; if (needle.ignorecase) flags += "i"; if (needle.multiline) flags += "m"; needle = regexp(needle.source, flags); } var m = this.match(needle); return m ? m.length : 0; } return 0; };
Comments
Post a Comment