//--------------------------------------------------------------------------- // RegExp object for Flash5 ActionScript Ver1.01 // Author: Pavils Jurjans // Email : pavils@mailbox.riga.lv // Default source for this file can be found at: // http://www.jurjans.lv/flash/RegExp.html //--------------------------------------------------------------------------- Object.RegExp = function() { if (arguments[0] == null) return null; this.const = "RegExp"; this.compile(arguments[0], arguments[1], arguments[2]); } Movieclip.prototype.RegExp = Object.RegExp; // Make it global String.prototype.invStr = function() { var s = this; var l = length(s); var j; var c; var r = ""; for (var i=1; i<255; i++) { c = chr(i); j = 0; while (j <= l && substring(s, 1+j++, 1) != c); if (j > l) r += c; } return r; } RegExp.prototype.compile = function() { this.source = arguments[0]; var flags = (arguments[1]+'').toLowerCase(); this.global = false; this.ignoreCase = false; this.multiline = false; for (var i=0; i type of match required: 0 = exact 1 = in char set 2 = not in char set 3 = paren 4 = ref to paren 7 = new "OR" section 9 = beginning of line 10 = end of line q[n].s --> character or character set q[n].a --> character has to repeat at least a times q[n].b --> character has to repeat at most b times */ var re = this.source; var ex; var l = length(re); var q = []; var qc = 0; var s; var range = false; var ca; var cb; var atEnd = false; for (i = i; i= (s=chr(ca++))) { thischar += s; } range = false; } else { if (s=="-" && length(thischar)>0) { //Character range is being defined range = true; } else { if (s == "\\") { //Predefined char set may follow s = substring(re, 1+i++, 1); if (s == "d") { thischar += "0123456789"; } else if (s == "D") { thischar += "0123456789".invStr(); } else if (s == "s") { thischar += " \f\n\r\t\v"; } else if (s == "S") { thischar += " \f\n\r\t\v".invStr(); } else if (s == "w") { thischar += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; } else if (s == "W") { thischar += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".invStr(); } else if (s == "b") { thischar += chr(8); } else if (s == "\\") { thischar += s; } } else { thischar += s; } } } } if (range) thischar += "-"; i--; var nextchar = substring(re, i+2, 1); } else if (thischar == "|") { //OR section if (atEnd) { q[qc].t = 10; q[qc].a = 1; q[qc].b = 1; qc++; q[qc] = new Object(); atEnd = false; } q[qc].t = 7; q[qc].a = 1; q[qc].b = 1; qc++; continue; } else if (thischar == ".") { q[qc].t = 2; thischar = "\n"; } else if (thischar == "*" || thischar == "?" || thischar == "+") { continue; } } else { if (thischar >= "1" && thischar <= "9") { q[qc].t = 4; } else if (thischar == "b") { q[qc].t = 1; thischar = "--wb--"; } else if (thischar == "B") { q[qc].t = 2; thischar = "--wb--"; } else if (thischar == "d") { q[qc].t = 1; thischar = "0123456789"; } else if (thischar == "D") { q[qc].t = 2; thischar = "0123456789"; } else if (thischar == "s") { q[qc].t = 1; thischar = " \f\n\r\t\v"; } else if (thischar == "S") { q[qc].t = 2; thischar = " \f\n\r\t\v"; } else if (thischar == "w") { q[qc].t = 1; thischar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; } else if (thischar == "W") { q[qc].t = 2; thischar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; } } //Counting metacharacters if (nextchar == "*") { q[qc].s = thischar; qc++; i++; } else if (nextchar == "?") { q[qc].s = thischar; q[qc].b = 1; qc++; i++; } else if (nextchar == "+") { q[qc].s = thischar; q[qc].a = 1; qc++; i++; } else if (nextchar == "{") { var comma = false; var rangeA = 0; range = "" i++; while (i+1 count of matches // q[n].i --> index within the string var str = arguments[0]+''; var re; var q = this._xq; var qc = this._xqc; var qb; var c; var cl; var ct; var s; var l = length(str); var ix = this.global ? this.lastIndex : 0; var ix_ = ix; var str_ = str; if (this.ignoreCase) str = str.toLowerCase(); var r = new Object(); r.i = -1; var i = -1; while (i < qc-1) { i++; if (RegExp.d) trace("New section started at i="+i); ix = ix_; qb = i; q[qb].c = -10; var atStart = RegExp._xp > 1; var atEnd = false; while (i > qb || ix < l+1) { if (q[i].t == 7) { //New "OR" section coming break; } else if (q[i].t == 9) { i++; if (i == qb+1) { atStart = true; qb = i; } q[qb].c = -10; continue; } else { if (r.i>=0 && ix>=r.i) { //There is already better match, so quit searching break; } if (q[i].c == -10) { if (RegExp.d) trace("Lookup #"+i+" at index "+ix+" for \'"+q[i].s+"\' type "+q[i].t); //Count the # of matches var m = 0; q[i].i = ix; if (q[i].t==0) { //Exact match c = this.ignoreCase ? q[i].s.toLowerCase() : q[i].s; while (m < q[i].b && ix < l) { if (substring(str, 1+ix, 1) == c) { m++; ix++; } else { break; } } } else if (q[i].t==1) { //In char set if (q[i].s == "--wb--") { q[i].a = 1; if (ix > 0 && ix < l) { ct = substring(str, ix, 1); if (ct == " " || ct == "\n") m = 1; if (m == 0) { ct = substring(str, 1+ix, 1); if (ct == " " || ct == "\n") m = 1; } } else { m = 1; } } else { c = this.ignoreCase ? q[i].s.toLowerCase() : q[i].s; cl = length(c); while (m < q[i].b && ix < l) { ct = substring(str, 1+ix, 1); cs = 0; while (cs <= cl && substring(c, 1+cs++, 1) != ct); if (cs <= cl) { m++; ix++; } else { break; } } } } else if (q[i].t==2) { //Not in char set c = this.ignoreCase ? q[i].s.toLowerCase() : q[i].s; cl = length(c); if (q[i].s == "--wb--") { q[i].a = 1; if (ix > 0 && ix < l) { ct = substring(str, ix, 1); s = substring(str, 1+ix, 1); if (ct != " " && ct != "\n" && s != " " && s != "\n") m = 1; } else { m = 0; } } else { while (m < q[i].b && ix < l) { ct = substring(str, 1+ix, 1); cs = 0; while (cs <= cl && substring(c, 1+cs++, 1) != ct); if (cs <= cl) { break; } else { m++; ix++; } } } } else if (q[i].t==10) { //End of string/line must be next s = substring(str, 1+ix, 1); m = (this.multiline && (s=="\n" || s=="\r")) || ix==l ? 1 : 0; } else if (q[i].t==3) { //Regular expression in parens re = q[i].s; q[i].ix = []; q[i].ix[m] = ix;//Save index if need to retreat re.lastIndex = ix; while (m < q[i].b && re.test(str_)) { cl = length(RegExp._xxlm); if (cl > 0) { ix += cl; m++; q[i].ix[m] = ix; } else { m = q[i].a; q[i].ix[m-1] = ix; break; } } if (m == 0) RegExp._xxlm = ""; if (re._xr > RegExp._xxlp) RegExp._xxlp = re._xr; RegExp._xxa[re._xr] = RegExp._xxlm; } else if (q[i].t==4) { //Back reference to paren if (RegExp._xp >= (c=Number(q[i].s))) { c = RegExp._xxa[c]; c = this.ignoreCase ? c.toLowerCase() : c; cl = length(c); q[i].ix = []; q[i].ix[m] = ix; if (cl > 0) { while (m < q[i].b && ix < l) { if (substring(str, 1+ix, cl) == c) { m++; ix += cl; q[i].ix[m] = ix; } else { break; } } } else { m = 0 q[i].a = 0; } } else { //Paren is not ready, treat number as charcode c = chr(c); q[i].ix = []; q[i].ix[m] = ix; while (m < q[i].b && ix < l) { if (substring(str, 1+ix, 1) == c) { m++; ix++; q[i].ix[m] = ix; } else { break; } } } } q[i].c = m; if (RegExp.d) trace(" "+m+" matches found"); } if (q[i].c < q[i].a) { if (RegExp.d) trace(" not enough matches"); //Not enough matches if (i > qb) { //Retreat back and decrease # of assumed matches i--; q[i].c--; if (q[i].c>=0) ix = (q[i].t == 3 || q[i].t == 4) ? q[i].ix[q[i].c] : (q[i].i + q[i].c); if (RegExp.d) trace("Retreat to #"+i+" c="+q[i].c+" index="+ix); } else { if (RegExp._xp > 1) { //If this is a paren, failing to find first match is fatal break; } if (atStart) { //Match must be at the start of string/line if (this.multiline) { //Jump to the beginning of the next line while (ix <= l) { s = substring(str, 1+ix++, 1); if (s == "\n" || s == "\r") break; } q[i].c = -10; } else { //No match break; } } else { //Start a new search from next position ix++; q[i].c = -10; } } } else { if (RegExp.d) trace(" enough matches!"); //# of matches ok, proceed to next i++; if (i==qc || q[i].t==7) { if (RegExp.d) trace("Saving better result: r.i = q["+qb+"].i = "+q[qb].i); r.i = q[qb].i; r.li = ix; break; } else { q[i].c = -10; } } } } while (i < qc && q[i].t != 7) i++;//Jump to the next "OR" section } if (r.i < 0) { this.lastIndex = 0; if (RegExp._xp-- == 1) { RegExp._xxa = []; RegExp._xxlp = 0; } return false; } else { ix = r.li; this._xi = r.i; RegExp._xxlm = substring(str_, r.i+1, ix-r.i); RegExp._xxlc = substring(str_, 1, r.i); RegExp._xxrc = substring(str_, ix+1, l-ix); if (ix == r.i) ix++; this.lastIndex = ix; if (RegExp._xp-- == 1) { RegExp.lastMatch = RegExp._xxlm; RegExp.leftContext = RegExp._xxlc; RegExp.rightContext = RegExp._xxrc; RegExp._xa = RegExp._xxa; RegExp.lastParen = RegExp._xxa[RegExp._xxlp]; for (i=1; i<10; i++) { RegExp["$"+i] = RegExp._xa[i]; } } return true; } } RegExp.prototype.exec = function() { var str = arguments[0]+''; if (str == '') return false; var t = this.test(str); if (t) { var ra = new Array(); ra.index = this._xi; ra.input = str; ra[0] = RegExp.lastMatch; var l = RegExp._xa.length; for (var i=1; i 9) { nrs += "$" + c; } else { nrs += RegExp._xa[Number(c)]; } } else { nrs += c; } pc = c; } r += substring(s, ix+1, re._xi-ix) + nrs; ix = re._xi + length(RegExp.lastMatch); ip = re.lastIndex; } re.lastIndex = ip; } else { if (re.test(s)) { r += RegExp.leftContext + rs; } } r += re.lastIndex == 0 ? s : RegExp.rightContext; return r; } String.prototype.search = function() { if (typeof(arguments[0]) != "object") return null; if (arguments[0].const != "RegExp") return null; var re = arguments[0]; var s = this; re.lastIndex = 0; var t = re.test(s) return t ? re._xi : -1; } String.prototype.old_split = String.prototype.split; String.prototype.split = function() { if (typeof(arguments[0]) == "object" && arguments[0].const == "RegExp") { var re = arguments[0]; var lm = arguments[1] == null ? 9999 : Number(arguments[1]); if (isNaN(lm)) lm = 9999; var s = this; var ra = new Array(); var rc = 0; var gs = re.global; re.global = true; re.lastIndex = 0; var ip = 0; var ipp = 0; var ix = 0; while (rc < lm && re.test(s)) { if (re._xi != ix) ra[rc++] = substring(s, ix+1, re._xi-ix); ix = re._xi + length(RegExp.lastMatch); ipp = ip; ip = re.lastIndex; } if (rc == lm) { re.lastIndex = ipp; } else { re.lastIndex = ip; } if (rc == 0) { ra[rc] = s; } else { if (rc < lm && length(RegExp.rightContext)>0) ra[rc++] = RegExp.rightContext; } re.global = gs; return ra; } else { return this.old_split(arguments[0], arguments[1]); } }