xregexp icon indicating copy to clipboard operation
xregexp copied to clipboard

bug ? addToken not work when XRegExp(pattern: RegExp)

Open bluelovers opened this issue 7 years ago • 4 comments
trafficstars

bug ? addToken not work when XRegExp(pattern: RegExp)

import addSupportToXRegExp, { IOptions } from 'xregexp-plugin-hanzi-cjk';
import * as XRegExp from 'xregexp';

let options: IOptions = {
	// set a flag if u only wanna trigger for this plugin, default is auto enable
	flags: '',
};

console.log(XRegExp.version);

// if didn't set xr, it is XRegExp
const xr1 = addSupportToXRegExp(null, options);
//const xr2 = addSupportToXRegExp(XRegExp, options);
//console.log('xr1 = xr2 = XRegExp', xr1 === xr2);

let r1 = '(の|像)';
let r2 = /(の|像)/;

// work when input is string
console.log(xr1(r1));
console.log(xr1(r1).test('象'));
console.log(xr1(r1).test('的'));

// fail when input is regexp
console.log(xr1(r2));
console.log(xr1(r2).test('象'));
console.log(xr1(r2).test('的'));
4.1.1
{ /([の之的]|[像象])/ xregexp: { captureNames: null, source: '(の|像)', flags: '' } }
true
true
{ /(の|像)/ xregexp: { captureNames: null, source: null, flags: null } }
false
false

bluelovers avatar Apr 24 '18 08:04 bluelovers

I think this is expected (or at least, somewhat documented) behavior. From https://github.com/slevithan/xregexp/blob/956747f50a0d40fb26796ba12b53969d67579f2e/src/xregexp.js#L544-L545:

Native regexes are recompiled using native (not XRegExp) syntax

You should be able to work around it by using xr1(r2.source) to instead of xr1(r2).

josephfrazier avatar Apr 24 '18 13:04 josephfrazier

@jfahrenkrug does official xregexp will do something like?

https://github.com/bluelovers/xregexp-plugin-hanzi-cjk/blob/0590c2f04e192f6968653f3b63b612ddd6acece7/index.ts#L73


and how can post code like u do?

bluelovers avatar Apr 24 '18 19:04 bluelovers

Yeah, as @josephfrazier said, this is intentional and documented (though perhaps the documentation could be more explicit). XRegExp has two modes: it either takes a regex pattern string with optional flags, or it makes a copy of an existing regex object you give it (rather than reinterpreting the regex object with XRegExp syntax), in which case flags are not accepted. If you want to use the source of an existing regex object as your pattern string, use <regexp>.source as @josephfrazier mentioned. Aside: Using XRegExp(/regex/) to copy a regex will extend the copy with XRegExp prototype methods/properties.

The way this works is that when you use XRegExp to copy regexes, it always uses RegExp under the hood. This improves perf and avoids unexpected outcomes where the result would not be a copy at all (especially when custom syntax tokens come into play).

Note that XRegExp's behavior for copying regexes was created prior to ES6. ES6 changed the handling of copying regexes using the RegExp constructor by allowing you to change regex flags in the process, which XRegExp does not (currently) support. This is not an especially useful feature (I think the only common use case is adding /g, and XRegExp offers globalize just for this), but nevertheless it's probably worth following ES6 by also allowing flags to be changed when using the XRegExp constructor to copy regexes. But adopting this feature would probably mean needing to always reparse with XRegExp, even if only to avoid inconsistent handling. Adopting the feature is doable even though XRegExp non-native flags can actually change the source of a regex, because XRegExp (as of v3.0.0) stores the pre-compilation source and flags (as <xregexp>.xregexp.source, separate from <xregexp>.source). You'd have to use that (in combination with the new flags) to make a copy.

slevithan avatar Apr 25 '18 05:04 slevithan

does official xregexp will do something like?

https://github.com/bluelovers/xregexp-plugin-hanzi-cjk/blob/0590c2f04e192f6968653f3b63b612ddd6acece7/index.ts#L73

Based on what @slevithan said above, it sounds like we want to preserve the performance characteristics of not reparsing RegExp objects passed into XRegExp(). You could always write a helper function that does this for you, of course.

and how can post code like u do?

Hmm, it seems like you did it correctly: https://blog.github.com/2017-08-15-introducing-embedded-code-snippets/

Maybe it only works for links to the repo being commented on...

josephfrazier avatar Apr 26 '18 02:04 josephfrazier