| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /*
- * Based on code from:
- *
- * XRegExp 1.5.0
- * (c) 2007-2010 Steven Levithan
- * MIT License
- * <http://xregexp.com>
- * Provides an augmented, extensible, cross-browser implementation of regular expressions,
- * including support for additional syntax, flags, and methods
- */
-
- define(function(require, exports, module) {
- "use strict";
- //---------------------------------
- // Private variables
- //---------------------------------
- var real = {
- exec: RegExp.prototype.exec,
- test: RegExp.prototype.test,
- match: String.prototype.match,
- replace: String.prototype.replace,
- split: String.prototype.split
- },
- compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
- compliantLastIndexIncrement = function () {
- var x = /^/g;
- real.test.call(x, "");
- return !x.lastIndex;
- }();
- if (compliantLastIndexIncrement && compliantExecNpcg)
- return;
- //---------------------------------
- // Overriden native methods
- //---------------------------------
- // Adds named capture support (with backreferences returned as `result.name`), and fixes two
- // cross-browser issues per ES3:
- // - Captured values for nonparticipating capturing groups should be returned as `undefined`,
- // rather than the empty string.
- // - `lastIndex` should not be incremented after zero-length matches.
- RegExp.prototype.exec = function (str) {
- var match = real.exec.apply(this, arguments),
- name, r2;
- if ( typeof(str) == 'string' && match) {
- // Fix browsers whose `exec` methods don't consistently return `undefined` for
- // nonparticipating capturing groups
- if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
- r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
- // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed
- // matching due to characters outside the match
- real.replace.call(str.slice(match.index), r2, function () {
- for (var i = 1; i < arguments.length - 2; i++) {
- if (arguments[i] === undefined)
- match[i] = undefined;
- }
- });
- }
- // Attach named capture properties
- 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];
- }
- }
- // Fix browsers that increment `lastIndex` after zero-length matches
- if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
- this.lastIndex--;
- }
- return match;
- };
- // Don't override `test` if it won't change anything
- if (!compliantLastIndexIncrement) {
- // Fix browser bug in native method
- RegExp.prototype.test = function (str) {
- // Use the native `exec` to skip some processing overhead, even though the overriden
- // `exec` would take care of the `lastIndex` fix
- var match = real.exec.call(this, str);
- // Fix browsers that increment `lastIndex` after zero-length matches
- if (match && this.global && !match[0].length && (this.lastIndex > match.index))
- this.lastIndex--;
- return !!match;
- };
- }
- //---------------------------------
- // Private helper functions
- //---------------------------------
- function getNativeFlags (regex) {
- return (regex.global ? "g" : "") +
- (regex.ignoreCase ? "i" : "") +
- (regex.multiline ? "m" : "") +
- (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3
- (regex.sticky ? "y" : "");
- }
- function indexOf (array, item, from) {
- if (Array.prototype.indexOf) // Use the native array method if available
- return array.indexOf(item, from);
- for (var i = from || 0; i < array.length; i++) {
- if (array[i] === item)
- return i;
- }
- return -1;
- }
- });
|