123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- var XRegExp;
- if (XRegExp) {
-
- throw Error("can't load XRegExp twice in the same frame");
- }
- (function (undefined) {
-
-
-
-
-
-
-
- XRegExp = function (pattern, flags) {
- var output = [],
- currScope = XRegExp.OUTSIDE_CLASS,
- pos = 0,
- context, tokenResult, match, chr, regex;
- if (XRegExp.isRegExp(pattern)) {
- if (flags !== undefined)
- throw TypeError("can't supply flags when constructing one RegExp from another");
- return clone(pattern);
- }
-
-
- if (isInsideConstructor)
- throw Error("can't call the XRegExp constructor within token definition functions");
- flags = flags || "";
- context = {
- hasNamedCapture: false,
- captureNames: [],
- hasFlag: function (flag) {return flags.indexOf(flag) > -1;},
- setFlag: function (flag) {flags += flag;}
- };
- while (pos < pattern.length) {
-
- tokenResult = runTokens(pattern, pos, currScope, context);
- if (tokenResult) {
- output.push(tokenResult.output);
- pos += (tokenResult.match[0].length || 1);
- } else {
-
-
- if (match = nativ.exec.call(nativeTokens[currScope], pattern.slice(pos))) {
- output.push(match[0]);
- pos += match[0].length;
- } else {
- chr = pattern.charAt(pos);
- if (chr === "[")
- currScope = XRegExp.INSIDE_CLASS;
- else if (chr === "]")
- currScope = XRegExp.OUTSIDE_CLASS;
-
- output.push(chr);
- pos++;
- }
- }
- }
- regex = RegExp(output.join(""), nativ.replace.call(flags, flagClip, ""));
- regex._xregexp = {
- source: pattern,
- captureNames: context.hasNamedCapture ? context.captureNames : null
- };
- return regex;
- };
-
-
-
- XRegExp.version = "1.5.1";
-
- XRegExp.INSIDE_CLASS = 1;
- XRegExp.OUTSIDE_CLASS = 2;
-
-
-
- var replacementToken = /\$(?:(\d\d?|[$&`'])|{([$\w]+)})/g,
- flagClip = /[^gimy]+|([\s\S])(?=[\s\S]*\1)/g,
- quantifier = /^(?:[?*+]|{\d+(?:,\d*)?})\??/,
- isInsideConstructor = false,
- tokens = [],
-
- nativ = {
- exec: RegExp.prototype.exec,
- test: RegExp.prototype.test,
- match: String.prototype.match,
- replace: String.prototype.replace,
- split: String.prototype.split
- },
- compliantExecNpcg = nativ.exec.call(/()??/, "")[1] === undefined,
- compliantLastIndexIncrement = function () {
- var x = /^/g;
- nativ.test.call(x, "");
- return !x.lastIndex;
- }(),
- hasNativeY = RegExp.prototype.sticky !== undefined,
- nativeTokens = {};
-
-
- nativeTokens[XRegExp.INSIDE_CLASS] = /^(?:\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S]))/;
- nativeTokens[XRegExp.OUTSIDE_CLASS] = /^(?:\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??)/;
-
-
-
-
-
-
-
- XRegExp.addToken = function (regex, handler, scope, trigger) {
- tokens.push({
- pattern: clone(regex, "g" + (hasNativeY ? "y" : "")),
- handler: handler,
- scope: scope || XRegExp.OUTSIDE_CLASS,
- trigger: trigger || null
- });
- };
-
-
-
- XRegExp.cache = function (pattern, flags) {
- var key = pattern + "/" + (flags || "");
- return XRegExp.cache[key] || (XRegExp.cache[key] = XRegExp(pattern, flags));
- };
-
-
-
-
- XRegExp.copyAsGlobal = function (regex) {
- return clone(regex, "g");
- };
-
-
-
- XRegExp.escape = function (str) {
- return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
- };
-
-
-
-
- XRegExp.execAt = function (str, regex, pos, anchored) {
- var r2 = clone(regex, "g" + ((anchored && hasNativeY) ? "y" : "")),
- match;
- r2.lastIndex = pos = pos || 0;
- match = r2.exec(str);
- if (anchored && match && match.index !== pos)
- match = null;
- if (regex.global)
- regex.lastIndex = match ? r2.lastIndex : 0;
- return match;
- };
-
-
- XRegExp.freezeTokens = function () {
- XRegExp.addToken = function () {
- throw Error("can't run addToken after freezeTokens");
- };
- };
-
-
-
-
- XRegExp.isRegExp = function (o) {
- return Object.prototype.toString.call(o) === "[object RegExp]";
- };
-
-
-
- XRegExp.iterate = function (str, regex, callback, context) {
- var r2 = clone(regex, "g"),
- i = -1, match;
- while (match = r2.exec(str)) {
- if (regex.global)
- regex.lastIndex = r2.lastIndex;
- callback.call(context, match, ++i, str, regex);
- if (r2.lastIndex === match.index)
- r2.lastIndex++;
- }
- if (regex.global)
- regex.lastIndex = 0;
- };
-
-
-
-
-
-
-
-
-
-
- XRegExp.matchChain = function (str, chain) {
- return function recurseChain (values, level) {
- var item = chain[level].regex ? chain[level] : {regex: chain[level]},
- regex = clone(item.regex, "g"),
- matches = [], i;
- for (i = 0; i < values.length; i++) {
- XRegExp.iterate(values[i], regex, function (match) {
- matches.push(item.backref ? (match[item.backref] || "") : match[0]);
- });
- }
- return ((level === chain.length - 1) || !matches.length) ?
- matches : recurseChain(matches, level + 1);
- }([str], 0);
- };
-
-
-
-
-
-
- RegExp.prototype.apply = function (context, args) {
- return this.exec(args[0]);
- };
-
-
- RegExp.prototype.call = function (context, str) {
- return this.exec(str);
- };
-
-
-
-
-
-
-
-
- RegExp.prototype.exec = function (str) {
- var match, name, r2, origLastIndex;
- if (!this.global)
- origLastIndex = this.lastIndex;
- match = nativ.exec.apply(this, arguments);
- if (match) {
-
-
- if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
- r2 = RegExp(this.source, nativ.replace.call(getNativeFlags(this), "g", ""));
-
-
- nativ.replace.call((str + "").slice(match.index), r2, function () {
- for (var i = 1; i < arguments.length - 2; i++) {
- if (arguments[i] === undefined)
- match[i] = undefined;
- }
- });
- }
-
- if (this._xregexp && this._xregexp.captureNames) {
- for (var i = 1; i < match.length; i++) {
- name = this._xregexp.captureNames[i - 1];
- if (name)
- match[name] = match[i];
- }
- }
-
- if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
- this.lastIndex--;
- }
- if (!this.global)
- this.lastIndex = origLastIndex;
- return match;
- };
-
- RegExp.prototype.test = function (str) {
-
-
- var match, origLastIndex;
- if (!this.global)
- origLastIndex = this.lastIndex;
- match = nativ.exec.call(this, str);
-
- if (match && !compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
- this.lastIndex--;
- if (!this.global)
- this.lastIndex = origLastIndex;
- return !!match;
- };
-
- String.prototype.match = function (regex) {
- if (!XRegExp.isRegExp(regex))
- regex = RegExp(regex);
- if (regex.global) {
- var result = nativ.match.apply(this, arguments);
- regex.lastIndex = 0;
- return result;
- }
- return regex.exec(this);
- };
-
-
-
-
-
-
- String.prototype.replace = function (search, replacement) {
- var isRegex = XRegExp.isRegExp(search),
- captureNames, result, str, origLastIndex;
-
-
-
-
- if (isRegex) {
- if (search._xregexp)
- captureNames = search._xregexp.captureNames;
- if (!search.global)
- origLastIndex = search.lastIndex;
- } else {
- search = search + "";
- }
- if (Object.prototype.toString.call(replacement) === "[object Function]") {
- result = nativ.replace.call(this + "", search, function () {
- if (captureNames) {
-
- arguments[0] = new String(arguments[0]);
-
- for (var i = 0; i < captureNames.length; i++) {
- if (captureNames[i])
- arguments[0][captureNames[i]] = arguments[i + 1];
- }
- }
-
- if (isRegex && search.global)
- search.lastIndex = arguments[arguments.length - 2] + arguments[0].length;
- return replacement.apply(null, arguments);
- });
- } else {
- str = this + "";
- result = nativ.replace.call(str, search, function () {
- var args = arguments;
- return nativ.replace.call(replacement + "", replacementToken, function ($0, $1, $2) {
-
- if ($1) {
- switch ($1) {
- case "$": return "$";
- case "&": return args[0];
- case "`": return args[args.length - 1].slice(0, args[args.length - 2]);
- case "'": return args[args.length - 1].slice(args[args.length - 2] + args[0].length);
-
- default:
-
-
-
-
-
-
-
-
- var literalNumbers = "";
- $1 = +$1;
- if (!$1)
- return $0;
- while ($1 > args.length - 3) {
- literalNumbers = String.prototype.slice.call($1, -1) + literalNumbers;
- $1 = Math.floor($1 / 10);
- }
- return ($1 ? args[$1] || "" : "$") + literalNumbers;
- }
-
- } else {
-
-
-
-
-
-
- var n = +$2;
- if (n <= args.length - 3)
- return args[n];
- n = captureNames ? indexOf(captureNames, $2) : -1;
- return n > -1 ? args[n + 1] : $0;
- }
- });
- });
- }
- if (isRegex) {
- if (search.global)
- search.lastIndex = 0;
- else
- search.lastIndex = origLastIndex;
- }
- return result;
- };
-
- String.prototype.split = function (s /* separator */, limit) {
-
- if (!XRegExp.isRegExp(s))
- return nativ.split.apply(this, arguments);
- var str = this + "",
- output = [],
- lastLastIndex = 0,
- match, lastLength;
-
-
-
-
-
-
- if (limit === undefined || +limit < 0) {
- limit = Infinity;
- } else {
- limit = Math.floor(+limit);
- if (!limit)
- return [];
- }
-
-
- s = XRegExp.copyAsGlobal(s);
- while (match = s.exec(str)) {
- if (s.lastIndex > lastLastIndex) {
- output.push(str.slice(lastLastIndex, match.index));
- if (match.length > 1 && match.index < str.length)
- Array.prototype.push.apply(output, match.slice(1));
- lastLength = match[0].length;
- lastLastIndex = s.lastIndex;
- if (output.length >= limit)
- break;
- }
- if (s.lastIndex === match.index)
- s.lastIndex++;
- }
- if (lastLastIndex === str.length) {
- if (!nativ.test.call(s, "") || lastLength)
- output.push("");
- } else {
- output.push(str.slice(lastLastIndex));
- }
- return output.length > limit ? output.slice(0, limit) : output;
- };
-
-
-
-
-
-
- function clone (regex, additionalFlags) {
- if (!XRegExp.isRegExp(regex))
- throw TypeError("type RegExp expected");
- var x = regex._xregexp;
- regex = XRegExp(regex.source, getNativeFlags(regex) + (additionalFlags || ""));
- if (x) {
- regex._xregexp = {
- source: x.source,
- captureNames: x.captureNames ? x.captureNames.slice(0) : null
- };
- }
- return regex;
- }
- function getNativeFlags (regex) {
- return (regex.global ? "g" : "") +
- (regex.ignoreCase ? "i" : "") +
- (regex.multiline ? "m" : "") +
- (regex.extended ? "x" : "") +
- (regex.sticky ? "y" : "");
- }
- function runTokens (pattern, index, scope, context) {
- var i = tokens.length,
- result, match, t;
-
- isInsideConstructor = true;
-
- try {
- while (i--) {
- t = tokens[i];
- if ((scope & t.scope) && (!t.trigger || t.trigger.call(context))) {
- t.pattern.lastIndex = index;
- match = t.pattern.exec(pattern);
- if (match && match.index === index) {
- result = {
- output: t.handler.call(context, match, scope),
- match: match
- };
- break;
- }
- }
- }
- } catch (err) {
- throw err;
- } finally {
- isInsideConstructor = false;
- }
- return result;
- }
- function indexOf (array, item, from) {
- if (Array.prototype.indexOf)
- return array.indexOf(item, from);
- for (var i = from || 0; i < array.length; i++) {
- if (array[i] === item)
- return i;
- }
- return -1;
- }
-
-
-
-
-
-
- XRegExp.addToken(
- /\(\?#[^)]*\)/,
- function (match) {
-
- return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)";
- }
- );
-
-
- XRegExp.addToken(
- /\((?!\?)/,
- function () {
- this.captureNames.push(null);
- return "(";
- }
- );
-
- XRegExp.addToken(
- /\(\?<([$\w]+)>/,
- function (match) {
- this.captureNames.push(match[1]);
- this.hasNamedCapture = true;
- return "(";
- }
- );
-
- XRegExp.addToken(
- /\\k<([\w$]+)>/,
- function (match) {
- var index = indexOf(this.captureNames, match[1]);
-
-
- return index > -1 ?
- "\\" + (index + 1) + (isNaN(match.input.charAt(match.index + match[0].length)) ? "" : "(?:)") :
- match[0];
- }
- );
-
- XRegExp.addToken(
- /\[\^?]/,
- function (match) {
-
-
- return match[0] === "[]" ? "\\b\\B" : "[\\s\\S]";
- }
- );
-
-
- XRegExp.addToken(
- /^\(\?([imsx]+)\)/,
- function (match) {
- this.setFlag(match[1]);
- return "";
- }
- );
-
- XRegExp.addToken(
- /(?:\s+|#.*)+/,
- function (match) {
-
- return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)";
- },
- XRegExp.OUTSIDE_CLASS,
- function () {return this.hasFlag("x");}
- );
-
- XRegExp.addToken(
- /\./,
- function () {return "[\\s\\S]";},
- XRegExp.OUTSIDE_CLASS,
- function () {return this.hasFlag("s");}
- );
-
-
-
-
-
- })();
|