@@ -446,7 +446,7 @@ var XRegExp = (function(undefined) {
446446 do {
447447 // Check for custom tokens at the current position
448448 tokenResult = runTokens ( pattern , flags , pos , scope , context ) ;
449- // If the matched token used the `reparse` option, splice its result into the
449+ // If the matched token used the `reparse` option, splice its output into the
450450 // pattern before running tokens again at the same position
451451 if ( tokenResult && tokenResult . reparse ) {
452452 pattern = pattern . slice ( 0 , pos ) +
@@ -459,7 +459,7 @@ var XRegExp = (function(undefined) {
459459 output += tokenResult . output ;
460460 pos += ( tokenResult . matchLength || 1 ) ;
461461 } else {
462- // Check for native tokens at the current position. This could use the native
462+ // Get the native token at the current position. This could use the native
463463 // `exec`, except that sticky processing avoids string slicing in browsers that
464464 // support flag y
465465 match = self . exec ( pattern , nativeTokens [ scope ] , pos , 'sticky' ) [ 0 ] ;
@@ -536,12 +536,26 @@ var XRegExp = (function(undefined) {
536536 * {scope: 'all'}
537537 * );
538538 * XRegExp('\\a[\\a-\\n]+').test('\x07\n\x07'); // -> true
539+ *
540+ * // Add the U (ungreedy) flag from PCRE and RE2, which reverses greedy and lazy quantifiers
541+ * XRegExp.addToken(
542+ * /([?*+]|{\d+(?:,\d*)?})(\??)/,
543+ * function(match) {return match[1] + (match[2] ? '' : '?');},
544+ * {flag: 'U'}
545+ * );
546+ * XRegExp('a+', 'U').exec('aaa')[0]; // -> 'a'
547+ * XRegExp('a+?', 'U').exec('aaa')[0]; // -> 'aaa'
539548 */
540549 self . addToken = function ( regex , handler , options ) {
541550 options = options || { } ;
551+ var optionalFlags = options . optionalFlags , i ;
542552
543- var optionalFlags = options . optionalFlags ,
544- i ;
553+ // Cannot use XRegExp regexes because the XRegExp construction process (in `runTokens`)
554+ // uses `XRegExp.exec`, which copies regexes the first time they're used. The copying thus
555+ // triggers an infinite loop, since it is building a new XRegExp
556+ if ( regex [ REGEX_DATA ] && ! regex [ REGEX_DATA ] . isNative ) {
557+ throw new Error ( 'Cannot use XRegExp regexes with addToken' ) ;
558+ }
545559
546560 if ( options . flag ) {
547561 registerFlag ( options . flag ) ;
0 commit comments