Best JavaScript code snippet using redwood
xregexp.js
Source:xregexp.js
...415 *416 * @private417 * @param {Boolean} on `true` to enable; `false` to disable.418 */419function setAstral(on) {420 features.astral = on;421}422/**423 * Returns the object, or throws an error if it is `null` or `undefined`. This is used to follow424 * the ES5 abstract operation `ToObject`.425 *426 * @private427 * @param {*} value Object to check and return.428 * @returns {*} The provided object.429 */430function toObject(value) {431 // null or undefined432 if (value == null) {433 throw new TypeError('Cannot convert null or undefined to object');434 }435 return value;436}437// ==--------------------------==438// Constructor439// ==--------------------------==440/**441 * Creates an extended regular expression object for matching text with a pattern. Differs from a442 * native regular expression in that additional syntax and flags are supported. The returned object443 * is in fact a native `RegExp` and works with all native methods.444 *445 * @class XRegExp446 * @constructor447 * @param {String|RegExp} pattern Regex pattern string, or an existing regex object to copy.448 * @param {String} [flags] Any combination of flags.449 * Native flags:450 * - `g` - global451 * - `i` - ignore case452 * - `m` - multiline anchors453 * - `u` - unicode (ES6)454 * - `y` - sticky (Firefox 3+, ES6)455 * Additional XRegExp flags:456 * - `n` - explicit capture457 * - `s` - dot matches all (aka singleline)458 * - `x` - free-spacing and line comments (aka extended)459 * - `A` - astral (requires the Unicode Base addon)460 * Flags cannot be provided when constructing one `RegExp` from another.461 * @returns {RegExp} Extended regular expression object.462 * @example463 *464 * // With named capture and flag x465 * XRegExp(`(?<year> [0-9]{4} ) -? # year466 * (?<month> [0-9]{2} ) -? # month467 * (?<day> [0-9]{2} ) # day`, 'x');468 *469 * // Providing a regex object copies it. Native regexes are recompiled using native (not XRegExp)470 * // syntax. Copies maintain extended data, are augmented with `XRegExp.prototype` properties, and471 * // have fresh `lastIndex` properties (set to zero).472 * XRegExp(/regex/);473 */474function XRegExp(pattern, flags) {475 if (XRegExp.isRegExp(pattern)) {476 if (flags !== undefined) {477 throw new TypeError('Cannot supply flags when copying a RegExp');478 }479 return copyRegex(pattern);480 }481 // Copy the argument behavior of `RegExp`482 pattern = pattern === undefined ? '' : String(pattern);483 flags = flags === undefined ? '' : String(flags);484 if (XRegExp.isInstalled('astral') && !(flags.indexOf('A') !== -1)) {485 // This causes an error to be thrown if the Unicode Base addon is not available486 flags += 'A';487 }488 if (!patternCache[pattern]) {489 patternCache[pattern] = {};490 }491 if (!patternCache[pattern][flags]) {492 var context = {493 hasNamedCapture: false,494 captureNames: []495 };496 var scope = defaultScope;497 var output = '';498 var pos = 0;499 var result = void 0;500 // Check for flag-related errors, and strip/apply flags in a leading mode modifier501 var applied = prepareFlags(pattern, flags);502 var appliedPattern = applied.pattern;503 var appliedFlags = applied.flags;504 // Use XRegExp's tokens to translate the pattern to a native regex pattern.505 // `appliedPattern.length` may change on each iteration if tokens use `reparse`506 while (pos < appliedPattern.length) {507 do {508 // Check for custom tokens at the current position509 result = runTokens(appliedPattern, appliedFlags, pos, scope, context);510 // If the matched token used the `reparse` option, splice its output into the511 // pattern before running tokens again at the same position512 if (result && result.reparse) {513 appliedPattern = appliedPattern.slice(0, pos) + result.output + appliedPattern.slice(pos + result.matchLength);514 }515 } while (result && result.reparse);516 if (result) {517 output += result.output;518 pos += result.matchLength || 1;519 } else {520 // Get the native token at the current position521 var token = XRegExp.exec(appliedPattern, nativeTokens[scope], pos, 'sticky')[0];522 output += token;523 pos += token.length;524 if (token === '[' && scope === defaultScope) {525 scope = classScope;526 } else if (token === ']' && scope === classScope) {527 scope = defaultScope;528 }529 }530 }531 patternCache[pattern][flags] = {532 // Use basic cleanup to collapse repeated empty groups like `(?:)(?:)` to `(?:)`. Empty533 // groups are sometimes inserted during regex transpilation in order to keep tokens534 // separated. However, more than one empty group in a row is never needed.535 pattern: nativ.replace.call(output, /(?:\(\?:\))+/g, '(?:)'),536 // Strip all but native flags537 flags: nativ.replace.call(appliedFlags, /[^gimuy]+/g, ''),538 // `context.captureNames` has an item for each capturing group, even if unnamed539 captures: context.hasNamedCapture ? context.captureNames : null540 };541 }542 var generated = patternCache[pattern][flags];543 return augment(new RegExp(generated.pattern, generated.flags), generated.captures, pattern, flags);544}545// Add `RegExp.prototype` to the prototype chain546XRegExp.prototype = /(?:)/;547// ==--------------------------==548// Public properties549// ==--------------------------==550/**551 * The XRegExp version number as a string containing three dot-separated parts. For example,552 * '2.0.0-beta-3'.553 *554 * @static555 * @memberOf XRegExp556 * @type String557 */558XRegExp.version = '4.0.0';559// ==--------------------------==560// Public methods561// ==--------------------------==562// Intentionally undocumented; used in tests and addons563XRegExp._clipDuplicates = clipDuplicates;564XRegExp._hasNativeFlag = hasNativeFlag;565XRegExp._dec = dec;566XRegExp._hex = hex;567XRegExp._pad4 = pad4;568/**569 * Extends XRegExp syntax and allows custom flags. This is used internally and can be used to570 * create XRegExp addons. If more than one token can match the same string, the last added wins.571 *572 * @memberOf XRegExp573 * @param {RegExp} regex Regex object that matches the new token.574 * @param {Function} handler Function that returns a new pattern string (using native regex syntax)575 * to replace the matched token within all future XRegExp regexes. Has access to persistent576 * properties of the regex being built, through `this`. Invoked with three arguments:577 * - The match array, with named backreference properties.578 * - The regex scope where the match was found: 'default' or 'class'.579 * - The flags used by the regex, including any flags in a leading mode modifier.580 * The handler function becomes part of the XRegExp construction process, so be careful not to581 * construct XRegExps within the function or you will trigger infinite recursion.582 * @param {Object} [options] Options object with optional properties:583 * - `scope` {String} Scope where the token applies: 'default', 'class', or 'all'.584 * - `flag` {String} Single-character flag that triggers the token. This also registers the585 * flag, which prevents XRegExp from throwing an 'unknown flag' error when the flag is used.586 * - `optionalFlags` {String} Any custom flags checked for within the token `handler` that are587 * not required to trigger the token. This registers the flags, to prevent XRegExp from588 * throwing an 'unknown flag' error when any of the flags are used.589 * - `reparse` {Boolean} Whether the `handler` function's output should not be treated as590 * final, and instead be reparseable by other tokens (including the current token). Allows591 * token chaining or deferring.592 * - `leadChar` {String} Single character that occurs at the beginning of any successful match593 * of the token (not always applicable). This doesn't change the behavior of the token unless594 * you provide an erroneous value. However, providing it can increase the token's performance595 * since the token can be skipped at any positions where this character doesn't appear.596 * @example597 *598 * // Basic usage: Add \a for the ALERT control code599 * XRegExp.addToken(600 * /\\a/,601 * () => '\\x07',602 * {scope: 'all'}603 * );604 * XRegExp('\\a[\\a-\\n]+').test('\x07\n\x07'); // -> true605 *606 * // Add the U (ungreedy) flag from PCRE and RE2, which reverses greedy and lazy quantifiers.607 * // Since `scope` is not specified, it uses 'default' (i.e., transformations apply outside of608 * // character classes only)609 * XRegExp.addToken(610 * /([?*+]|{\d+(?:,\d*)?})(\??)/,611 * (match) => `${match[1]}${match[2] ? '' : '?'}`,612 * {flag: 'U'}613 * );614 * XRegExp('a+', 'U').exec('aaa')[0]; // -> 'a'615 * XRegExp('a+?', 'U').exec('aaa')[0]; // -> 'aaa'616 */617XRegExp.addToken = function (regex, handler, options) {618 options = options || {};619 var optionalFlags = options.optionalFlags;620 var i = void 0;621 if (options.flag) {622 registerFlag(options.flag);623 }624 if (optionalFlags) {625 optionalFlags = nativ.split.call(optionalFlags, '');626 for (i = 0; i < optionalFlags.length; ++i) {627 registerFlag(optionalFlags[i]);628 }629 }630 // Add to the private list of syntax tokens631 tokens.push({632 regex: copyRegex(regex, {633 addG: true,634 addY: hasNativeY,635 isInternalOnly: true636 }),637 handler: handler,638 scope: options.scope || defaultScope,639 flag: options.flag,640 reparse: options.reparse,641 leadChar: options.leadChar642 });643 // Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and flags644 // might now produce different results645 XRegExp.cache.flush('patterns');646};647/**648 * Caches and returns the result of calling `XRegExp(pattern, flags)`. On any subsequent call with649 * the same pattern and flag combination, the cached copy of the regex is returned.650 *651 * @memberOf XRegExp652 * @param {String} pattern Regex pattern string.653 * @param {String} [flags] Any combination of XRegExp flags.654 * @returns {RegExp} Cached XRegExp object.655 * @example656 *657 * while (match = XRegExp.cache('.', 'gs').exec(str)) {658 * // The regex is compiled once only659 * }660 */661XRegExp.cache = function (pattern, flags) {662 if (!regexCache[pattern]) {663 regexCache[pattern] = {};664 }665 return regexCache[pattern][flags] || (regexCache[pattern][flags] = XRegExp(pattern, flags));666};667// Intentionally undocumented; used in tests668XRegExp.cache.flush = function (cacheName) {669 if (cacheName === 'patterns') {670 // Flush the pattern cache used by the `XRegExp` constructor671 patternCache = {};672 } else {673 // Flush the regex cache populated by `XRegExp.cache`674 regexCache = {};675 }676};677/**678 * Escapes any regular expression metacharacters, for use when matching literal strings. The result679 * can safely be used at any point within a regex that uses any flags.680 *681 * @memberOf XRegExp682 * @param {String} str String to escape.683 * @returns {String} String with regex metacharacters escaped.684 * @example685 *686 * XRegExp.escape('Escaped? <.>');687 * // -> 'Escaped\?\ <\.>'688 */689XRegExp.escape = function (str) {690 return nativ.replace.call(toObject(str), /[-\[\]{}()*+?.,\\^$|#\s]/g, '\\$&');691};692/**693 * Executes a regex search in a specified string. Returns a match array or `null`. If the provided694 * regex uses named capture, named backreference properties are included on the match array.695 * Optional `pos` and `sticky` arguments specify the search start position, and whether the match696 * must start at the specified position only. The `lastIndex` property of the provided regex is not697 * used, but is updated for compatibility. Also fixes browser bugs compared to the native698 * `RegExp.prototype.exec` and can be used reliably cross-browser.699 *700 * @memberOf XRegExp701 * @param {String} str String to search.702 * @param {RegExp} regex Regex to search with.703 * @param {Number} [pos=0] Zero-based index at which to start the search.704 * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position705 * only. The string `'sticky'` is accepted as an alternative to `true`.706 * @returns {Array} Match array with named backreference properties, or `null`.707 * @example708 *709 * // Basic use, with named backreference710 * let match = XRegExp.exec('U+2620', XRegExp('U\\+(?<hex>[0-9A-F]{4})'));711 * match.hex; // -> '2620'712 *713 * // With pos and sticky, in a loop714 * let pos = 2, result = [], match;715 * while (match = XRegExp.exec('<1><2><3><4>5<6>', /<(\d)>/, pos, 'sticky')) {716 * result.push(match[1]);717 * pos = match.index + match[0].length;718 * }719 * // result -> ['2', '3', '4']720 */721XRegExp.exec = function (str, regex, pos, sticky) {722 var cacheKey = 'g';723 var addY = false;724 var fakeY = false;725 var match = void 0;726 addY = hasNativeY && !!(sticky || regex.sticky && sticky !== false);727 if (addY) {728 cacheKey += 'y';729 } else if (sticky) {730 // Simulate sticky matching by appending an empty capture to the original regex. The731 // resulting regex will succeed no matter what at the current index (set with `lastIndex`),732 // and will not search the rest of the subject string. We'll know that the original regex733 // has failed if that last capture is `''` rather than `undefined` (i.e., if that last734 // capture participated in the match).735 fakeY = true;736 cacheKey += 'FakeY';737 }738 regex[REGEX_DATA] = regex[REGEX_DATA] || {};739 // Shares cached copies with `XRegExp.match`/`replace`740 var r2 = regex[REGEX_DATA][cacheKey] || (regex[REGEX_DATA][cacheKey] = copyRegex(regex, {741 addG: true,742 addY: addY,743 source: fakeY ? regex.source + '|()' : undefined,744 removeY: sticky === false,745 isInternalOnly: true746 }));747 pos = pos || 0;748 r2.lastIndex = pos;749 // Fixed `exec` required for `lastIndex` fix, named backreferences, etc.750 match = fixed.exec.call(r2, str);751 // Get rid of the capture added by the pseudo-sticky matcher if needed. An empty string means752 // the original regexp failed (see above).753 if (fakeY && match && match.pop() === '') {754 match = null;755 }756 if (regex.global) {757 regex.lastIndex = match ? r2.lastIndex : 0;758 }759 return match;760};761/**762 * Executes a provided function once per regex match. Searches always start at the beginning of the763 * string and continue until the end, regardless of the state of the regex's `global` property and764 * initial `lastIndex`.765 *766 * @memberOf XRegExp767 * @param {String} str String to search.768 * @param {RegExp} regex Regex to search with.769 * @param {Function} callback Function to execute for each match. Invoked with four arguments:770 * - The match array, with named backreference properties.771 * - The zero-based match index.772 * - The string being traversed.773 * - The regex object being used to traverse the string.774 * @example775 *776 * // Extracts every other digit from a string777 * const evens = [];778 * XRegExp.forEach('1a2345', /\d/, (match, i) => {779 * if (i % 2) evens.push(+match[0]);780 * });781 * // evens -> [2, 4]782 */783XRegExp.forEach = function (str, regex, callback) {784 var pos = 0;785 var i = -1;786 var match = void 0;787 while (match = XRegExp.exec(str, regex, pos)) {788 // Because `regex` is provided to `callback`, the function could use the deprecated/789 // nonstandard `RegExp.prototype.compile` to mutate the regex. However, since `XRegExp.exec`790 // doesn't use `lastIndex` to set the search position, this can't lead to an infinite loop,791 // at least. Actually, because of the way `XRegExp.exec` caches globalized versions of792 // regexes, mutating the regex will not have any effect on the iteration or matched strings,793 // which is a nice side effect that brings extra safety.794 callback(match, ++i, str, regex);795 pos = match.index + (match[0].length || 1);796 }797};798/**799 * Copies a regex object and adds flag `g`. The copy maintains extended data, is augmented with800 * `XRegExp.prototype` properties, and has a fresh `lastIndex` property (set to zero). Native801 * regexes are not recompiled using XRegExp syntax.802 *803 * @memberOf XRegExp804 * @param {RegExp} regex Regex to globalize.805 * @returns {RegExp} Copy of the provided regex with flag `g` added.806 * @example807 *808 * const globalCopy = XRegExp.globalize(/regex/);809 * globalCopy.global; // -> true810 */811XRegExp.globalize = function (regex) {812 return copyRegex(regex, { addG: true });813};814/**815 * Installs optional features according to the specified options. Can be undone using816 * `XRegExp.uninstall`.817 *818 * @memberOf XRegExp819 * @param {Object|String} options Options object or string.820 * @example821 *822 * // With an options object823 * XRegExp.install({824 * // Enables support for astral code points in Unicode addons (implicitly sets flag A)825 * astral: true826 * });827 *828 * // With an options string829 * XRegExp.install('astral');830 */831XRegExp.install = function (options) {832 options = prepareOptions(options);833 if (!features.astral && options.astral) {834 setAstral(true);835 }836};837/**838 * Checks whether an individual optional feature is installed.839 *840 * @memberOf XRegExp841 * @param {String} feature Name of the feature to check. One of:842 * - `astral`843 * @returns {Boolean} Whether the feature is installed.844 * @example845 *846 * XRegExp.isInstalled('astral');847 */848XRegExp.isInstalled = function (feature) {849 return !!features[feature];850};851/**852 * Returns `true` if an object is a regex; `false` if it isn't. This works correctly for regexes853 * created in another frame, when `instanceof` and `constructor` checks would fail.854 *855 * @memberOf XRegExp856 * @param {*} value Object to check.857 * @returns {Boolean} Whether the object is a `RegExp` object.858 * @example859 *860 * XRegExp.isRegExp('string'); // -> false861 * XRegExp.isRegExp(/regex/i); // -> true862 * XRegExp.isRegExp(RegExp('^', 'm')); // -> true863 * XRegExp.isRegExp(XRegExp('(?s).')); // -> true864 */865XRegExp.isRegExp = function (value) {866 return toString.call(value) === '[object RegExp]';867}; // isType(value, 'RegExp');868/**869 * Returns the first matched string, or in global mode, an array containing all matched strings.870 * This is essentially a more convenient re-implementation of `String.prototype.match` that gives871 * the result types you actually want (string instead of `exec`-style array in match-first mode,872 * and an empty array instead of `null` when no matches are found in match-all mode). It also lets873 * you override flag g and ignore `lastIndex`, and fixes browser bugs.874 *875 * @memberOf XRegExp876 * @param {String} str String to search.877 * @param {RegExp} regex Regex to search with.878 * @param {String} [scope='one'] Use 'one' to return the first match as a string. Use 'all' to879 * return an array of all matched strings. If not explicitly specified and `regex` uses flag g,880 * `scope` is 'all'.881 * @returns {String|Array} In match-first mode: First match as a string, or `null`. In match-all882 * mode: Array of all matched strings, or an empty array.883 * @example884 *885 * // Match first886 * XRegExp.match('abc', /\w/); // -> 'a'887 * XRegExp.match('abc', /\w/g, 'one'); // -> 'a'888 * XRegExp.match('abc', /x/g, 'one'); // -> null889 *890 * // Match all891 * XRegExp.match('abc', /\w/g); // -> ['a', 'b', 'c']892 * XRegExp.match('abc', /\w/, 'all'); // -> ['a', 'b', 'c']893 * XRegExp.match('abc', /x/, 'all'); // -> []894 */895XRegExp.match = function (str, regex, scope) {896 var global = regex.global && scope !== 'one' || scope === 'all';897 var cacheKey = (global ? 'g' : '') + (regex.sticky ? 'y' : '') || 'noGY';898 regex[REGEX_DATA] = regex[REGEX_DATA] || {};899 // Shares cached copies with `XRegExp.exec`/`replace`900 var r2 = regex[REGEX_DATA][cacheKey] || (regex[REGEX_DATA][cacheKey] = copyRegex(regex, {901 addG: !!global,902 removeG: scope === 'one',903 isInternalOnly: true904 }));905 var result = nativ.match.call(toObject(str), r2);906 if (regex.global) {907 regex.lastIndex = scope === 'one' && result ?908 // Can't use `r2.lastIndex` since `r2` is nonglobal in this case909 result.index + result[0].length : 0;910 }911 return global ? result || [] : result && result[0];912};913/**914 * Retrieves the matches from searching a string using a chain of regexes that successively search915 * within previous matches. The provided `chain` array can contain regexes and or objects with916 * `regex` and `backref` properties. When a backreference is specified, the named or numbered917 * backreference is passed forward to the next regex or returned.918 *919 * @memberOf XRegExp920 * @param {String} str String to search.921 * @param {Array} chain Regexes that each search for matches within preceding results.922 * @returns {Array} Matches by the last regex in the chain, or an empty array.923 * @example924 *925 * // Basic usage; matches numbers within <b> tags926 * XRegExp.matchChain('1 <b>2</b> 3 <b>4 a 56</b>', [927 * XRegExp('(?is)<b>.*?</b>'),928 * /\d+/929 * ]);930 * // -> ['2', '4', '56']931 *932 * // Passing forward and returning specific backreferences933 * html = '<a href="http://xregexp.com/api/">XRegExp</a>\934 * <a href="http://www.google.com/">Google</a>';935 * XRegExp.matchChain(html, [936 * {regex: /<a href="([^"]+)">/i, backref: 1},937 * {regex: XRegExp('(?i)^https?://(?<domain>[^/?#]+)'), backref: 'domain'}938 * ]);939 * // -> ['xregexp.com', 'www.google.com']940 */941XRegExp.matchChain = function (str, chain) {942 return function recurseChain(values, level) {943 var item = chain[level].regex ? chain[level] : { regex: chain[level] };944 var matches = [];945 function addMatch(match) {946 if (item.backref) {947 // Safari 4.0.5 (but not 5.0.5+) inappropriately uses sparse arrays to hold the948 // `undefined`s for backreferences to nonparticipating capturing groups. In such949 // cases, a `hasOwnProperty` or `in` check on its own would inappropriately throw950 // the exception, so also check if the backreference is a number that is within the951 // bounds of the array.952 if (!(match.hasOwnProperty(item.backref) || +item.backref < match.length)) {953 throw new ReferenceError('Backreference to undefined group: ' + item.backref);954 }955 matches.push(match[item.backref] || '');956 } else {957 matches.push(match[0]);958 }959 }960 for (var i = 0; i < values.length; ++i) {961 XRegExp.forEach(values[i], item.regex, addMatch);962 }963 return level === chain.length - 1 || !matches.length ? matches : recurseChain(matches, level + 1);964 }([str], 0);965};966/**967 * Returns a new string with one or all matches of a pattern replaced. The pattern can be a string968 * or regex, and the replacement can be a string or a function to be called for each match. To969 * perform a global search and replace, use the optional `scope` argument or include flag g if using970 * a regex. Replacement strings can use `${n}` or `$<n>` for named and numbered backreferences.971 * Replacement functions can use named backreferences via `arguments[0].name`. Also fixes browser972 * bugs compared to the native `String.prototype.replace` and can be used reliably cross-browser.973 *974 * @memberOf XRegExp975 * @param {String} str String to search.976 * @param {RegExp|String} search Search pattern to be replaced.977 * @param {String|Function} replacement Replacement string or a function invoked to create it.978 * Replacement strings can include special replacement syntax:979 * - $$ - Inserts a literal $ character.980 * - $&, $0 - Inserts the matched substring.981 * - $` - Inserts the string that precedes the matched substring (left context).982 * - $' - Inserts the string that follows the matched substring (right context).983 * - $n, $nn - Where n/nn are digits referencing an existent capturing group, inserts984 * backreference n/nn.985 * - ${n}, $<n> - Where n is a name or any number of digits that reference an existent capturing986 * group, inserts backreference n.987 * Replacement functions are invoked with three or more arguments:988 * - The matched substring (corresponds to $& above). Named backreferences are accessible as989 * properties of this first argument.990 * - 0..n arguments, one for each backreference (corresponding to $1, $2, etc. above).991 * - The zero-based index of the match within the total search string.992 * - The total string being searched.993 * @param {String} [scope='one'] Use 'one' to replace the first match only, or 'all'. If not994 * explicitly specified and using a regex with flag g, `scope` is 'all'.995 * @returns {String} New string with one or all matches replaced.996 * @example997 *998 * // Regex search, using named backreferences in replacement string999 * const name = XRegExp('(?<first>\\w+) (?<last>\\w+)');1000 * XRegExp.replace('John Smith', name, '$<last>, $<first>');1001 * // -> 'Smith, John'1002 *1003 * // Regex search, using named backreferences in replacement function1004 * XRegExp.replace('John Smith', name, (match) => `${match.last}, ${match.first}`);1005 * // -> 'Smith, John'1006 *1007 * // String search, with replace-all1008 * XRegExp.replace('RegExp builds RegExps', 'RegExp', 'XRegExp', 'all');1009 * // -> 'XRegExp builds XRegExps'1010 */1011XRegExp.replace = function (str, search, replacement, scope) {1012 var isRegex = XRegExp.isRegExp(search);1013 var global = search.global && scope !== 'one' || scope === 'all';1014 var cacheKey = (global ? 'g' : '') + (search.sticky ? 'y' : '') || 'noGY';1015 var s2 = search;1016 if (isRegex) {1017 search[REGEX_DATA] = search[REGEX_DATA] || {};1018 // Shares cached copies with `XRegExp.exec`/`match`. Since a copy is used, `search`'s1019 // `lastIndex` isn't updated *during* replacement iterations1020 s2 = search[REGEX_DATA][cacheKey] || (search[REGEX_DATA][cacheKey] = copyRegex(search, {1021 addG: !!global,1022 removeG: scope === 'one',1023 isInternalOnly: true1024 }));1025 } else if (global) {1026 s2 = new RegExp(XRegExp.escape(String(search)), 'g');1027 }1028 // Fixed `replace` required for named backreferences, etc.1029 var result = fixed.replace.call(toObject(str), s2, replacement);1030 if (isRegex && search.global) {1031 // Fixes IE, Safari bug (last tested IE 9, Safari 5.1)1032 search.lastIndex = 0;1033 }1034 return result;1035};1036/**1037 * Performs batch processing of string replacements. Used like `XRegExp.replace`, but accepts an1038 * array of replacement details. Later replacements operate on the output of earlier replacements.1039 * Replacement details are accepted as an array with a regex or string to search for, the1040 * replacement string or function, and an optional scope of 'one' or 'all'. Uses the XRegExp1041 * replacement text syntax, which supports named backreference properties via `${name}` or1042 * `$<name>`.1043 *1044 * @memberOf XRegExp1045 * @param {String} str String to search.1046 * @param {Array} replacements Array of replacement detail arrays.1047 * @returns {String} New string with all replacements.1048 * @example1049 *1050 * str = XRegExp.replaceEach(str, [1051 * [XRegExp('(?<name>a)'), 'z${name}'],1052 * [/b/gi, 'y'],1053 * [/c/g, 'x', 'one'], // scope 'one' overrides /g1054 * [/d/, 'w', 'all'], // scope 'all' overrides lack of /g1055 * ['e', 'v', 'all'], // scope 'all' allows replace-all for strings1056 * [/f/g, ($0) => $0.toUpperCase()]1057 * ]);1058 */1059XRegExp.replaceEach = function (str, replacements) {1060 var i = void 0;1061 var r = void 0;1062 for (i = 0; i < replacements.length; ++i) {1063 r = replacements[i];1064 str = XRegExp.replace(str, r[0], r[1], r[2]);1065 }1066 return str;1067};1068/**1069 * Splits a string into an array of strings using a regex or string separator. Matches of the1070 * separator are not included in the result array. However, if `separator` is a regex that contains1071 * capturing groups, backreferences are spliced into the result each time `separator` is matched.1072 * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably1073 * cross-browser.1074 *1075 * @memberOf XRegExp1076 * @param {String} str String to split.1077 * @param {RegExp|String} separator Regex or string to use for separating the string.1078 * @param {Number} [limit] Maximum number of items to include in the result array.1079 * @returns {Array} Array of substrings.1080 * @example1081 *1082 * // Basic use1083 * XRegExp.split('a b c', ' ');1084 * // -> ['a', 'b', 'c']1085 *1086 * // With limit1087 * XRegExp.split('a b c', ' ', 2);1088 * // -> ['a', 'b']1089 *1090 * // Backreferences in result array1091 * XRegExp.split('..word1..', /([a-z]+)(\d+)/i);1092 * // -> ['..', 'word', '1', '..']1093 */1094XRegExp.split = function (str, separator, limit) {1095 return fixed.split.call(toObject(str), separator, limit);1096};1097/**1098 * Executes a regex search in a specified string. Returns `true` or `false`. Optional `pos` and1099 * `sticky` arguments specify the search start position, and whether the match must start at the1100 * specified position only. The `lastIndex` property of the provided regex is not used, but is1101 * updated for compatibility. Also fixes browser bugs compared to the native1102 * `RegExp.prototype.test` and can be used reliably cross-browser.1103 *1104 * @memberOf XRegExp1105 * @param {String} str String to search.1106 * @param {RegExp} regex Regex to search with.1107 * @param {Number} [pos=0] Zero-based index at which to start the search.1108 * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position1109 * only. The string `'sticky'` is accepted as an alternative to `true`.1110 * @returns {Boolean} Whether the regex matched the provided value.1111 * @example1112 *1113 * // Basic use1114 * XRegExp.test('abc', /c/); // -> true1115 *1116 * // With pos and sticky1117 * XRegExp.test('abc', /c/, 0, 'sticky'); // -> false1118 * XRegExp.test('abc', /c/, 2, 'sticky'); // -> true1119 */1120// Do this the easy way :-)1121XRegExp.test = function (str, regex, pos, sticky) {1122 return !!XRegExp.exec(str, regex, pos, sticky);1123};1124/**1125 * Uninstalls optional features according to the specified options. All optional features start out1126 * uninstalled, so this is used to undo the actions of `XRegExp.install`.1127 *1128 * @memberOf XRegExp1129 * @param {Object|String} options Options object or string.1130 * @example1131 *1132 * // With an options object1133 * XRegExp.uninstall({1134 * // Disables support for astral code points in Unicode addons1135 * astral: true1136 * });1137 *1138 * // With an options string1139 * XRegExp.uninstall('astral');1140 */1141XRegExp.uninstall = function (options) {1142 options = prepareOptions(options);1143 if (features.astral && options.astral) {1144 setAstral(false);1145 }1146};1147/**1148 * Returns an XRegExp object that is the union of the given patterns. Patterns can be provided as1149 * regex objects or strings. Metacharacters are escaped in patterns provided as strings.1150 * Backreferences in provided regex objects are automatically renumbered to work correctly within1151 * the larger combined pattern. Native flags used by provided regexes are ignored in favor of the1152 * `flags` argument.1153 *1154 * @memberOf XRegExp1155 * @param {Array} patterns Regexes and strings to combine.1156 * @param {String} [flags] Any combination of XRegExp flags.1157 * @param {Object} [options] Options object with optional properties:1158 * - `conjunction` {String} Type of conjunction to use: 'or' (default) or 'none'....
regexp.js
Source:regexp.js
...150 }151 }152 return result;153 }154 function setAstral(on) {155 self.cache.flush("patterns");156 features.astral = on;157 }158 function setNatives(on) {159 RegExp.prototype.exec = (on ? fixed : nativ).exec;160 RegExp.prototype.test = (on ? fixed : nativ).test;161 String.prototype.match = (on ? fixed : nativ).match;162 String.prototype.replace = (on ? fixed : nativ).replace;163 String.prototype.split = (on ? fixed : nativ).split;164 features.natives = on;165 }166 function toObject(value) {167 if (value == null) {168 throw new TypeError("Cannot convert null or undefined to object");169 }170 return value;171 }172 self = function (pattern, flags) {173 var context = {174 hasNamedCapture: false,175 captureNames: []176 },177 scope = defaultScope,178 output = "",179 pos = 0,180 result, token, key;181 if (self.isRegExp(pattern)) {182 if (flags !== undefined) {183 throw new TypeError("Cannot supply flags when copying a RegExp");184 }185 return copy(pattern, {186 addProto: true187 });188 }189 pattern = pattern === undefined ? "" : String(pattern);190 flags = flags === undefined ? "" : String(flags);191 key = pattern + "***" + flags;192 if (!patternCache[key]) {193 result = prepareFlags(pattern, flags);194 pattern = result.pattern;195 flags = result.flags;196 while (pos < pattern.length) {197 do {198 result = runTokens(pattern, flags, pos, scope, context);199 if (result && result.reparse) {200 pattern = pattern.slice(0, pos) + result.output + pattern.slice(pos + result.matchLength);201 }202 } while (result && result.reparse);203 if (result) {204 output += result.output;205 pos += result.matchLength || 1;206 } else {207 token = self.exec(pattern, nativeTokens[scope], pos, "sticky")[0];208 output += token;209 pos += token.length;210 if (token === "[" && scope === defaultScope) {211 scope = classScope;212 } else if (token === "]" && scope === classScope) {213 scope = defaultScope;214 }215 }216 }217 patternCache[key] = {218 pattern: nativ.replace.call(output, / \ (\ ? : \)( ? = \ (\ ? : \)) | ^ \ (\ ? : \) | \ (\ ? : \) $ / g, ""),219 flags: nativ.replace.call(flags, / [ ^ gimy] + /g, ""),220 captures: context.hasNamedCapture ? context.captureNames : null221 };222 }223 key = patternCache[key];224 return augment(new RegExp(key.pattern, key.flags), key.captures, true);225 };226 self.prototype = new RegExp();227 self.version = "3.0.0-pre";228 self.addToken = function(regex, handler, options) {229 options = options || {};230 var optionalFlags = options.optionalFlags, i;231 if (options.flag) {232 registerFlag(options.flag);233 }234 if (optionalFlags) {235 optionalFlags = nativ.split.call(optionalFlags, "");236 for (i = 0; i < optionalFlags.length; ++i) {237 registerFlag(optionalFlags[i]);238 }239 }240 tokens.push({241 regex: copy(regex, {242 add: "g" + (hasNativeY ? "y" : "")243 }),244 handler: handler,245 scope: options.scope || defaultScope,246 flag: options.flag,247 reparse: options.reparse248 });249 self.cache.flush("patterns");250 };251 self.cache = function(pattern, flags) {252 var key = pattern + "***" + (flags || "");253 return cache[key] || (cache[key] = self(pattern, flags));254 };255 self.cache.flush = function(cacheName) {256 if (cacheName === "patterns") {257 patternCache = {};258 } else {259 cache = {};260 }261 };262 self.escape = function(str) {263 return nativ.replace.call(toObject(str), / [-[\] {}() * + ? ., \\ ^ $ | #\s] / g, "\\$&");264 };265 self.exec = function (str, regex, pos, sticky) {266 var cacheFlags = "g",267 match, r2;268 if (hasNativeY && (sticky || regex.sticky && sticky !== false)) {269 cacheFlags += "y";270 }271 regex[REGEX_DATA] = regex[REGEX_DATA] || getBaseProps();272 r2 = regex[REGEX_DATA][cacheFlags] || (regex[REGEX_DATA][cacheFlags] = copy(regex, {273 add: cacheFlags,274 remove: sticky === false ? "y" : ""275 }));276 r2.lastIndex = pos = pos || 0;277 match = fixed.exec.call(r2, str);278 if (sticky && match && match.index !== pos) {279 match = null;280 }281 if (regex.global) {282 regex.lastIndex = match ? r2.lastIndex : 0;283 }284 return match;285 };286 self.forEach = function (str, regex, callback, context) {287 var pos = 0, i = -1, match288 ;//=================================================289 while (match = self.exec(str, regex, pos)) {290 callback.call(context, match, ++i, str, regex);291 pos = match.index + (match[0].length || 1);292 }293 return context;294 };295 self.globalize = function (regex) {296 return copy(regex, {297 add: "g",298 addProto: true299 });300 };301 self.install = function (options) {302 options = prepareOptions(options);303 if (!features.astral && options.astral) {304 setAstral(true);305 }306 if (!features.natives && options.natives) {307 setNatives(true);308 }309 };310 self.isInstalled = function (feature) {311 return !!features[feature];312 };313 self.isRegExp = function (value) {314 return toString.call(value) === "[object RegExp]";315 };316 self.match = function (str, regex, scope) {317 var global = regex.global && scope !== "one" || scope === "all"318 , cacheFlags = (global ? "g" : "") + (regex.sticky ? "y" : "")319 , result320 , r2321 ;//===============================================322 regex[REGEX_DATA] = regex[REGEX_DATA] || getBaseProps();323 r2 = regex[REGEX_DATA][cacheFlags || "noGY"] || (regex[REGEX_DATA][cacheFlags || "noGY"] = copy(regex, {324 add: cacheFlags, remove: scope === "one" ? "g" : ""325 }));326 result = nativ.match.call(toObject(str), r2);327 if (regex.global) {328 regex.lastIndex = scope === "one" && result ? result.index + result[0].length : 0;329 }330 return global ? result || [] : result && result[0];331 };332 self.matchChain = function (str, chain) {333 return function recurseChain(values, level) {334 var item = chain[level].regex ? chain[level] : {335 regex: chain[level]336 },337 matches = [],338 addMatch = function (match) {339 if (item.backref) {340 if (!(match.hasOwnProperty(item.backref) || +item.backref < match.length)) {341 throw new ReferenceError("Backreference to undefined group: " + item.backref);342 }343 matches.push(match[item.backref] || "");344 } else {345 matches.push(match[0]);346 }347 },348 i;349 for (i = 0; i < values.length; ++i) {350 self.forEach(values[i], item.regex, addMatch);351 }352 return level === chain.length - 1 || !matches.length ? matches : recurseChain(matches, level + 1);353 }([str], 0);354 };355 self.replace = function (str, search, replacement, scope) {356 var isRegex = self.isRegExp(search),357 global = search.global && scope !== "one" || scope === "all",358 cacheFlags = (global ? "g" : "") + (search.sticky ? "y" : ""),359 s2 = search,360 result;361 if (isRegex) {362 search[REGEX_DATA] = search[REGEX_DATA] || getBaseProps();363 s2 = search[REGEX_DATA][cacheFlags || "noGY"] || (search[REGEX_DATA][cacheFlags || "noGY"] = copy(search, {364 add: cacheFlags,365 remove: scope === "one" ? "g" : ""366 }));367 } else if (global) {368 s2 = new RegExp(self.escape(String(search)), "g");369 }370 result = fixed.replace.call(toObject(str), s2, replacement);371 if (isRegex && search.global) {372 search.lastIndex = 0;373 }374 return result;375 };376 self.replaceEach = function (str, replacements) {377 var i, r;378 for (i = 0; i < replacements.length; ++i) {379 r = replacements[i];380 str = self.replace(str, r[0], r[1], r[2]);381 }382 return str;383 };384 self.split = function (str, separator, limit) {385 return fixed.split.call(toObject(str), separator, limit);386 };387 self.test = function (str, regex, pos, sticky) {388 return !!self.exec(str, regex, pos, sticky);389 };390 self.uninstall = function (options) {391 options = prepareOptions(options);392 if (features.astral && options.astral) {393 setAstral(false);394 }395 if (features.natives && options.natives) {396 setNatives(false);397 }398 };399 self.union = function (patterns, flags) {400 var parts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g,401 output = [],402 numCaptures = 0,403 numPriorCaptures, captureNames, pattern, rewrite = function (match, paren, backref) {404 var name = captureNames[numCaptures - numPriorCaptures];405 if (paren) {406 ++numCaptures;407 if (name) {...
Using AI Code Generation
1import { setAstral } from '@redwoodjs/graphql-server'2import { db } from 'src/lib/db'3export const users = () => {4 return db.user.findMany()5}6export const user = ({ id }) => {7 return db.user.findUnique({8 where: { id },9 })10}11export const createUser = ({ input }) => {12 const { name, email } = input13 setAstral('user', 'name', name)14 return db.user.create({15 })16}17export const updateUser = ({ id, input }) => {18 return db.user.update({19 where: { id },20 })21}22export const deleteUser = ({ id }) => {23 return db.user.delete({24 where: { id },25 })26}27export const User = {28 posts: (_obj, { root }) =>29 db.user.findUnique({ where: { id: root.id } }).posts(),30}
Using AI Code Generation
1var redwood = require('redwood');2var r = new redwood.Redwood();3r.setAstral(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);4var redwood = require('redwood');5var r = new redwood.Redwood();6r.setAstral(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);7var redwood = require('redwood');8var r = new redwood.Redwood();9r.setAstral(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);10var redwood = require('redwood');11var r = new redwood.Redwood();12r.setAstral(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);13var redwood = require('redwood');14var r = new redwood.Redwood();15var astral = r.getAstral();16var redwood = require('redwood');17var r = new redwood.Redwood();18r.setSolar(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);19var redwood = require('redwood');20var r = new redwood.Redwood();21var solar = r.getSolar();
Using AI Code Generation
1var redwood = require('redwood');2var redwoodClient = new redwood.RedwoodClient();3redwoodClient.setAstral('astral', function (err, result) {4 if (err) {5 console.log(err);6 return;7 }8 console.log(result);9});10var redwood = require('redwood');11var redwoodClient = new redwood.RedwoodClient();12redwoodClient.getAstral('astral', function (err, result) {13 if (err) {14 console.log(err);15 return;16 }17 console.log(result);18});19var redwood = require('redwood');20var redwoodClient = new redwood.RedwoodClient();21redwoodClient.setAstral('astral', function (err, result) {22 if (err) {23 console.log(err);24 return;25 }26 console.log(result);27});28var redwood = require('redwood');29var redwoodClient = new redwood.RedwoodClient();30redwoodClient.getAstral('astral', function (err, result) {31 if (err) {32 console.log(err);33 return;34 }35 console.log(result);36});37var redwood = require('redwood');38var redwoodClient = new redwood.RedwoodClient();39redwoodClient.setAstral('astral', function (err, result) {40 if (err) {41 console.log(err);42 return;43 }44 console.log(result);45});46var redwood = require('redwood');47var redwoodClient = new redwood.RedwoodClient();48redwoodClient.getAstral('astral', function (err, result) {49 if (err) {50 console.log(err);51 return;52 }53 console.log(result);54});55var redwood = require('redwood');56var redwoodClient = new redwood.RedwoodClient();57redwoodClient.setAstral('astral
Using AI Code Generation
1var redwood = require('redwood');2redwood.setAstral({3});4redwood.init("test", "test");5redwood.log("info", "test");6var redwood = require('redwood');7redwood.setAstral({8});9redwood.init("test2", "test2");10redwood.log("info", "test2");
Using AI Code Generation
1var redwood = require('redwood-js');2var rw = new redwood.Redwood();3var location = {latitude: 37.7749295, longitude: -122.4194155};4var date = new Date();5rw.setAstral(location, date);6var redwood = require('redwood-js');7var rw = new redwood.Redwood();8var location = {latitude: 37.7749295, longitude: -122.4194155};9var date = new Date();10rw.getAstral(location, date);11var redwood = require('redwood-js');12var rw = new redwood.Redwood();13var location = {latitude: 37.7749295, longitude: -122.4194155};14var date = new Date();15rw.getAstral(location, date);16var redwood = require('redwood-js');17var rw = new redwood.Redwood();18var location = {latitude: 37.7749295, longitude: -122.4194155};19var date = new Date();20rw.getAstral(location, date);21var redwood = require('redwood-js');22var rw = new redwood.Redwood();23var location = {latitude: 37.7749295, longitude: -122.4194155};24var date = new Date();25rw.getAstral(location, date);26var redwood = require('redwood-js');27var rw = new redwood.Redwood();28var location = {latitude: 37.7749295, longitude: -122.4194155};29var date = new Date();30rw.getAstral(location, date);31var redwood = require('redwood-js');32var rw = new redwood.Redwood();33var location = {latitude: 37.7749295, longitude: -122.4194155};34var date = new Date();35rw.getAstral(location,
Using AI Code Generation
1var redwood = require('redwood');2var myAstral = redwood.setAstral(2012, 8, 21, 11, 11, 11, 11);3console.log(myAstral);4var redwood = require('redwood');5var myAstral = redwood.getAstral();6console.log(myAstral);7var redwood = require('redwood');8var myAstral = redwood.getAstral();9console.log(myAstral);10var redwood = require('redwood');11var myAstral = redwood.getAstral();12console.log(myAstral);13var redwood = require('redwood');14var myAstral = redwood.getAstral();15console.log(myAstral);16var redwood = require('redwood');17var myAstral = redwood.getAstral();18console.log(myAstral);19var redwood = require('redwood');20var myAstral = redwood.getAstral();21console.log(myAstral);22var redwood = require('redwood');23var myAstral = redwood.getAstral();24console.log(myAstral);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!