Giter VIP home page Giter VIP logo

regenerate's Issues

Optimization / โ€œbugโ€ with ranges

regenerate.fromCodePoints([ 0x20, 0x21 ]);
// โ†’ '[\\x20\\x21] (correct)

regenerate.fromCodePoints([ 0x20, 0x21, 0x23 ]);
// โ†’ '[\\x20-\\x21\\x23]', which works fine, but just '[\\x20\\x21\\x23]' would be better

Non-minimal regex when adding a second range lower than the first

With the specific following instructions, regenerate produces a non-minimal (but correct) regex:

regenerate().addRange( 99, 100 ).addRange( 65, 99 ).toString()
'[cdA-c]'

By switching the order, we have a correct minimal regex:

regenerate().addRange( 65, 99 ).addRange( 99, 100 ).toString()
'[A-d]'

Playing a bit with the boundaries, it seems it only occur when the end of the second range is exactly the same as the start of the first range.

Bug in `.remove(set)`?

var ID_Start = regenerate(require('unicode-6.3.0/properties/ID_Start/code-points'));
var ID_Continue = regenerate(require('unicode-6.3.0/properties/ID_Continue/code-points'));
var set = ID_Continue.clone().remove(ID_Start);

setโ€™s data structure looks messed up. Hereโ€™s the first 20 entries:

[ '30', // odd = start
  '3a', // even = end (exclusive, so at least 1 higher than `start`)
  '5f',
  '60',
  'b7',
  'b8',
  '300',
  '370',
  '375', // start
  '375', // end โ†’ WTF
  '387',
  '388',
  '38b', // start
  '38b', // end โ†’ WTF
  '483',
  '488',
  '591',
  '5be',
  '5bf',
  '5c0' ]

Invert regular expression?

I wonder if it's possible to negate the resulting regexp in regenerate.

One could apparently use negative look-ahead (like (?!expr)), but it is said to perform bad. One could also invert the result of regexp.test(str) but it might not be ideal either.

How would I go about to "flip" the ranges? Ideally, there would be a built-in method .invert(). Another possible approach would be to add the entire range of Unicode characters, then use .remove() and .removeRange() on that.

Avoid overhead of calling `dataFromCodePoints()` etc. internally

When passing CodePointSets as arguments, e.g. setC = regenerate(setA).difference(setB), the overhead of calling dataFromCodePoints() etc. internally can be avoided. We could optimize these cases, although itโ€™s debatable whether itโ€™s worth it.

For difference specifically, we could do something similar to what @inimino uses, now that we use the same data structure:

function dataDifferenceData(dataA, dataB) {
  var ret = [];
  var i = 0;
  var j = 0;
  var a;
  var b;
  var al = dataA.length;
  var bl = dataB.length;
  var last;
  var state = 0;
  if (!al) {
    return [];
  }
  if (!bl) {
    return dataA;
  }
  a = dataA[0];
  b = dataB[0];
  if (isNaN(a) || isNaN(b)) {
    throw Error('cset_difference: bad input');
  }
  for (;;) {
    if (a < b) {
      if (!(state & 1)) {
        if (a == last) {
          ret.pop();
        }
        else {
          ret.push(a);
        }
        last = a;
      }
      state ^= 2;
      a = ++i < al ? dataA[i] : 0x110000;
    } else {
      if (a == 0x110000 && b == 0x110000) {
        return ret;
      }
      if (state & 2) {
        if (b == last) {
          ret.pop();
        } else {
          ret.push(b);
        }
        last = b;
      }
      state ^= 1;
      b = ++j < bl ? dataB[j] : 0x110000;
    }
  }
}

Add `regenerate.prototype.remove(fn)`

Things like regenerate(codePoints).removeRange(0x010000, 0x10FFFF) are very slow, since it creates an array containing all the code points in that range, and then walks through the code points looking for matches.

Something like this would be a much faster solution in that case:

regenerate(codePoints).remove(function(codePoint) {
  return codePoint > 0xFFFF; // remove astral code points from the set
});

Incorrect optimization in surrogateMappings

The surrogate pair of 0x1F610 is \uD83D\uDE10 and it got lost during some RegExp optimizations.
Consider this test case:

const set = regenerate().addRange(0x1F000, 0x1F1FF).addRange(0x1F300, 0x1F5FF).add(0x1F610);
const testChar = String.fromCodePoint(0x1F610);

The RegExp in Unicode mode is correct:

console.log(set.toRegExp('u'));    // /[\u{1F000}-\u{1F1FF}\u{1F300}-\u{1F5FF}\u{1F610}]/u
testChar.match(set.toRegExp('u')); // match found

The RegExp in "legacy" mode is incorrect (missing surrogate pair for 0x1F610):

console.log(set.toRegExp());    // /[\uD83C\uD83D][\uDC00-\uDDFF\uDF00-\uDFFF]/
testChar.match(set.toRegExp()); // null

I know that patches are welcome, but I don't have spare time right now. Will look into the source code later :-)

Script to convert any Regenerate set to code that generates it

This is not really a bug report, but rather a script that is useful when generating test cases:

regenerate.prototype.toCode = function() {
    var data = this.data;
    // Iterate over the data per `(start, end)` pair.
    var index = 0;
    var start;
    var end;
    var length = data.length;
    var loneCodePoints = [];
    var ranges = [];
    while (index < length) {
        start = data[index];
        end = data[index + 1] - 1; // Note: the `- 1` makes `end` inclusive.
        if (start == end) {
            loneCodePoints.push('0x' + start.toString(16).toUpperCase());
        } else {
            ranges.push(
                'addRange(0x' + start.toString(16).toUpperCase() +
                ', 0x' + end.toString(16).toUpperCase() + ')'
            );
        }
        index += 2;
    }
    return 'regenerate(' + loneCodePoints.join(', ') + ')' +
        (ranges.length ? '.' + ranges.join('.') : '');
};

var set = regenerate(0x1D306, 'a').addRange(0x2CEE, 0x4DFF);
console.log(set.toCode());
// โ†’ 'regenerate(0x61, 0x1D306).addRange(0x2CEE, 0x4DFF)'

Letโ€™s allow extending regenerate.prototype for plugins like this.

Allow chaining

E.g.

regenerate(regenerate.range(0x0000, 0x000A))
    .add(0x1D306)
    .add([0x00A9, 0x0192])
    .addRange(0x0100, 0x0200)
    .remove(0x0002)
    .removeRange(0x0100, 0x0190)
    .difference([0x0004, 0x0007])
    .intersection([0x192, 0x196])
    .toString();
    // [\\u0192\\u0192\\u0196]

(Silly example, but you get the idea.)

Avoid `Array#splice` where possible

As an optimization, we should replace calls to array.splice(a, b, c) where b=1 with just array[a] = c (and similar for other argument counts).

Add `difference` and others

// get an array of all BMP code points except U+0067, U+23FC, and U+F3FC
var codePoints = regenerate.difference(regenerate.range(0x0, 0xFFFF), [0x67, 0x23FC, 0xF3FC]);

Maybe also these:

union(array1, array2) / add(array1, array2)
intersect(array1, array2)
remove(array1, array2)

Improve performance / decrease memory usage

At the moment, Regenerate internally stores an array of all code points in the current set in memory. This is nice and easy, but it gets pretty slow for large sets of code points. It might be better to make this array smaller by making use of ranges. For example, instead of:

[0, 1, 2, 3, 4, 5, 6, 10, 12, 13, 14, 15, 18]

โ€ฆwe could just store something like:

[[0, 6], 10, [12, 15], 18]

This would require a complete rewrite of Regenerate, though.

Write a fuzzer to try and find more bugs

We can use Regenerate v0.5.4 (for which the output is 100% trustworthy), patch its codePointToSymbol to the latest version, and then compare its results with v0.6.x results. Any differences in output are most likely definitely bugs.

Unexpected matches in the resulting RegExp

I was trying to use this for twemoji but I've found a very weird behavior I'm not sure it's me doing it wrong or there's a bug in here (haven't checked your source code yet).

So, the resulting RegExp matches # and every char between 0 and 9 and I've no idea what's going on and why is that, so I've prepared this test code:

var list = ["๐Ÿ‡จ๐Ÿ‡ณ", "๐Ÿ‡บ๐Ÿ‡ธ", "๐Ÿ‡ท๐Ÿ‡บ", "๐Ÿ‡ฐ๐Ÿ‡ท", "๐Ÿ‡ฏ๐Ÿ‡ต", "๐Ÿ‡ฎ๐Ÿ‡น", "๐Ÿ‡ฌ๐Ÿ‡ง", "๐Ÿ‡ซ๐Ÿ‡ท", "๐Ÿ‡ช๐Ÿ‡ธ", "๐Ÿ‡ฉ๐Ÿ‡ช", "9โƒฃ", "8โƒฃ", "7โƒฃ", "6โƒฃ", "5โƒฃ", "4โƒฃ", "3โƒฃ", "2โƒฃ", "1โƒฃ", "0โƒฃ", "#โƒฃ", "๐Ÿšณ", "๐Ÿšฑ", "๐Ÿšฐ", "๐Ÿšฏ", "๐Ÿšฎ", "๐Ÿšฆ", "๐Ÿšฃ", "๐Ÿšก", "๐Ÿš ", "๐ŸšŸ", "๐Ÿšž", "๐Ÿš", "๐Ÿšœ", "๐Ÿš›", "๐Ÿš˜", "๐Ÿš–", "๐Ÿš”", "๐Ÿš", "๐ŸšŽ", "๐Ÿš", "๐Ÿš‹", "๐ŸšŠ", "๐Ÿšˆ", "๐Ÿš†", "๐Ÿš‚", "๐Ÿš", "๐Ÿ˜ถ", "๐Ÿ˜ด", "๐Ÿ˜ฏ", "๐Ÿ˜ฎ", "๐Ÿ˜ฌ", "๐Ÿ˜ง", "๐Ÿ˜ฆ", "๐Ÿ˜Ÿ", "๐Ÿ˜›", "๐Ÿ˜™", "๐Ÿ˜—", "๐Ÿ˜•", "๐Ÿ˜‘", "๐Ÿ˜", "๐Ÿ˜Ž", "๐Ÿ˜ˆ", "๐Ÿ˜‡", "๐Ÿ˜€", "๐Ÿ•ง", "๐Ÿ•ฆ", "๐Ÿ•ฅ", "๐Ÿ•ค", "๐Ÿ•ฃ", "๐Ÿ•ข", "๐Ÿ•ก", "๐Ÿ• ", "๐Ÿ•Ÿ", "๐Ÿ•ž", "๐Ÿ•", "๐Ÿ•œ", "๐Ÿ”ญ", "๐Ÿ”ฌ", "๐Ÿ”•", "๐Ÿ”‰", "๐Ÿ”ˆ", "๐Ÿ”‡", "๐Ÿ”†", "๐Ÿ”…", "๐Ÿ”„", "๐Ÿ”‚", "๐Ÿ”", "๐Ÿ”€", "๐Ÿ“ต", "๐Ÿ“ฏ", "๐Ÿ“ญ", "๐Ÿ“ฌ", "๐Ÿ’ท", "๐Ÿ’ถ", "๐Ÿ’ญ", "๐Ÿ‘ญ", "๐Ÿ‘ฌ", "๐Ÿ‘ฅ", "๐Ÿช", "๐Ÿ–", "๐Ÿ•", "๐Ÿ“", "๐Ÿ", "๐Ÿ", "๐Ÿ‹", "๐ŸŠ", "๐Ÿ‰", "๐Ÿˆ", "๐Ÿ‡", "๐Ÿ†", "๐Ÿ…", "๐Ÿ„", "๐Ÿƒ", "๐Ÿ‚", "๐Ÿ", "๐Ÿ€", "๐Ÿค", "๐Ÿ‰", "๐Ÿ‡", "๐Ÿผ", "๐Ÿ", "๐Ÿ‹", "๐ŸŒณ", "๐ŸŒฒ", "๐ŸŒž", "๐ŸŒ", "๐ŸŒœ", "๐ŸŒš", "๐ŸŒ˜", "๐Ÿƒ", "๐Ÿ…ฐ", "๐Ÿ…ฑ", "๐Ÿ…พ", "๐Ÿ†Ž", "๐Ÿ†‘", "๐Ÿ†’", "๐Ÿ†“", "๐Ÿ†”", "๐Ÿ†•", "๐Ÿ†–", "๐Ÿ†—", "๐Ÿ†˜", "๐Ÿ†™", "๐Ÿ†š", "๐Ÿ‘ท", "๐Ÿ›…", "๐Ÿ›„", "๐Ÿ›ƒ", "๐Ÿ›‚", "๐Ÿ›", "๐Ÿšฟ", "๐Ÿšธ", "๐Ÿšท", "๐Ÿšต", "๐Ÿˆ", "๐Ÿˆ‚", "๐Ÿˆฒ", "๐Ÿˆณ", "๐Ÿˆด", "๐Ÿˆต", "๐Ÿˆถ", "๐Ÿˆท", "๐Ÿˆธ", "๐Ÿˆน", "๐Ÿˆบ", "๐Ÿ‰", "๐Ÿ‰‘", "๐ŸŒ€", "๐ŸŒ", "๐ŸŒ‚", "๐ŸŒƒ", "๐ŸŒ„", "๐ŸŒ…", "๐ŸŒ†", "๐ŸŒ‡", "๐ŸŒˆ", "๐ŸŒ‰", "๐ŸŒŠ", "๐ŸŒ‹", "๐ŸŒŒ", "๐ŸŒ", "๐ŸŒ‘", "๐ŸŒ“", "๐ŸŒ”", "๐ŸŒ•", "๐ŸŒ™", "๐ŸŒ›", "๐ŸŒŸ", "๐ŸŒ ", "๐ŸŒฐ", "๐ŸŒฑ", "๐ŸŒด", "๐ŸŒต", "๐ŸŒท", "๐ŸŒธ", "๐ŸŒน", "๐ŸŒบ", "๐ŸŒป", "๐ŸŒผ", "๐ŸŒฝ", "๐ŸŒพ", "๐ŸŒฟ", "๐Ÿ€", "๐Ÿ", "๐Ÿ‚", "๐Ÿƒ", "๐Ÿ„", "๐Ÿ…", "๐Ÿ†", "๐Ÿ‡", "๐Ÿˆ", "๐Ÿ‰", "๐ŸŠ", "๐ŸŒ", "๐Ÿ", "๐ŸŽ", "๐Ÿ", "๐Ÿ‘", "๐Ÿ’", "๐Ÿ“", "๐Ÿ”", "๐Ÿ•", "๐Ÿ–", "๐Ÿ—", "๐Ÿ˜", "๐Ÿ™", "๐Ÿš", "๐Ÿ›", "๐Ÿœ", "๐Ÿ", "๐Ÿž", "๐ŸŸ", "๐Ÿ ", "๐Ÿก", "๐Ÿข", "๐Ÿฃ", "๐Ÿค", "๐Ÿฅ", "๐Ÿฆ", "๐Ÿง", "๐Ÿจ", "๐Ÿฉ", "๐Ÿช", "๐Ÿซ", "๐Ÿฌ", "๐Ÿญ", "๐Ÿฎ", "๐Ÿฏ", "๐Ÿฐ", "๐Ÿฑ", "๐Ÿฒ", "๐Ÿณ", "๐Ÿด", "๐Ÿต", "๐Ÿถ", "๐Ÿท", "๐Ÿธ", "๐Ÿน", "๐Ÿบ", "๐Ÿป", "๐ŸŽ€", "๐ŸŽ", "๐ŸŽ‚", "๐ŸŽƒ", "๐ŸŽ„", "๐ŸŽ…", "๐ŸŽ†", "๐ŸŽ‡", "๐ŸŽˆ", "๐ŸŽ‰", "๐ŸŽŠ", "๐ŸŽ‹", "๐ŸŽŒ", "๐ŸŽ", "๐ŸŽŽ", "๐ŸŽ", "๐ŸŽ", "๐ŸŽ‘", "๐ŸŽ’", "๐ŸŽ“", "๐ŸŽ ", "๐ŸŽก", "๐ŸŽข", "๐ŸŽฃ", "๐ŸŽค", "๐ŸŽฅ", "๐ŸŽฆ", "๐ŸŽง", "๐ŸŽจ", "๐ŸŽฉ", "๐ŸŽช", "๐ŸŽซ", "๐ŸŽฌ", "๐ŸŽญ", "๐ŸŽฎ", "๐ŸŽฏ", "๐ŸŽฐ", "๐ŸŽฑ", "๐ŸŽฒ", "๐ŸŽณ", "๐ŸŽด", "๐ŸŽต", "๐ŸŽถ", "๐ŸŽท", "๐ŸŽธ", "๐ŸŽน", "๐ŸŽบ", "๐ŸŽป", "๐ŸŽผ", "๐ŸŽฝ", "๐ŸŽพ", "๐ŸŽฟ", "๐Ÿ€", "๐Ÿ", "๐Ÿ‚", "๐Ÿƒ", "๐Ÿ„", "๐Ÿ†", "๐Ÿˆ", "๐ŸŠ", "๐Ÿ ", "๐Ÿก", "๐Ÿข", "๐Ÿฃ", "๐Ÿฅ", "๐Ÿฆ", "๐Ÿง", "๐Ÿจ", "๐Ÿฉ", "๐Ÿช", "๐Ÿซ", "๐Ÿฌ", "๐Ÿญ", "๐Ÿฎ", "๐Ÿฏ", "๐Ÿฐ", "๐ŸŒ", "๐Ÿ", "๐ŸŽ", "๐Ÿ‘", "๐Ÿ’", "๐Ÿ”", "๐Ÿ—", "๐Ÿ˜", "๐Ÿ™", "๐Ÿš", "๐Ÿ›", "๐Ÿœ", "๐Ÿ", "๐Ÿž", "๐ŸŸ", "๐Ÿ ", "๐Ÿก", "๐Ÿข", "๐Ÿฃ", "๐Ÿค", "๐Ÿฅ", "๐Ÿฆ", "๐Ÿง", "๐Ÿจ", "๐Ÿฉ", "๐Ÿซ", "๐Ÿฌ", "๐Ÿญ", "๐Ÿฎ", "๐Ÿฏ", "๐Ÿฐ", "๐Ÿฑ", "๐Ÿฒ", "๐Ÿณ", "๐Ÿด", "๐Ÿต", "๐Ÿถ", "๐Ÿท", "๐Ÿธ", "๐Ÿน", "๐Ÿบ", "๐Ÿป", "๐Ÿผ", "๐Ÿฝ", "๐Ÿพ", "๐Ÿ‘€", "๐Ÿ‘‚", "๐Ÿ‘ƒ", "๐Ÿ‘„", "๐Ÿ‘…", "๐Ÿ‘†", "๐Ÿ‘‡", "๐Ÿ‘ˆ", "๐Ÿ‘‰", "๐Ÿ‘Š", "๐Ÿ‘‹", "๐Ÿ‘Œ", "๐Ÿ‘", "๐Ÿ‘Ž", "๐Ÿ‘", "๐Ÿ‘", "๐Ÿ‘‘", "๐Ÿ‘’", "๐Ÿ‘“", "๐Ÿ‘”", "๐Ÿ‘•", "๐Ÿ‘–", "๐Ÿ‘—", "๐Ÿ‘˜", "๐Ÿ‘™", "๐Ÿ‘š", "๐Ÿ‘›", "๐Ÿ‘œ", "๐Ÿ‘", "๐Ÿ‘ž", "๐Ÿ‘Ÿ", "๐Ÿ‘ ", "๐Ÿ‘ก", "๐Ÿ‘ข", "๐Ÿ‘ฃ", "๐Ÿ‘ค", "๐Ÿ‘ฆ", "๐Ÿ‘ง", "๐Ÿ‘จ", "๐Ÿ‘ฉ", "๐Ÿ‘ช", "๐Ÿ‘ซ", "๐Ÿ‘ฎ", "๐Ÿ‘ฏ", "๐Ÿ‘ฐ", "๐Ÿ‘ฑ", "๐Ÿ‘ฒ", "๐Ÿ‘ณ", "๐Ÿ‘ด", "๐Ÿ‘ต", "๐Ÿ‘ถ", "๐Ÿšด", "๐Ÿ‘ธ", "๐Ÿ‘น", "๐Ÿ‘บ", "๐Ÿ‘ป", "๐Ÿ‘ผ", "๐Ÿ‘ฝ", "๐Ÿ‘พ", "๐Ÿ‘ฟ", "๐Ÿ’€", "๐Ÿ’", "๐Ÿ’‚", "๐Ÿ’ƒ", "๐Ÿ’„", "๐Ÿ’…", "๐Ÿ’†", "๐Ÿ’‡", "๐Ÿ’ˆ", "๐Ÿ’‰", "๐Ÿ’Š", "๐Ÿ’‹", "๐Ÿ’Œ", "๐Ÿ’", "๐Ÿ’Ž", "๐Ÿ’", "๐Ÿ’", "๐Ÿ’‘", "๐Ÿ’’", "๐Ÿ’“", "๐Ÿ’”", "๐Ÿ’•", "๐Ÿ’–", "๐Ÿ’—", "๐Ÿ’˜", "๐Ÿ’™", "๐Ÿ’š", "๐Ÿ’›", "๐Ÿ’œ", "๐Ÿ’", "๐Ÿ’ž", "๐Ÿ’Ÿ", "๐Ÿ’ ", "๐Ÿ’ก", "๐Ÿ’ข", "๐Ÿ’ฃ", "๐Ÿ’ค", "๐Ÿ’ฅ", "๐Ÿ’ฆ", "๐Ÿ’ง", "๐Ÿ’จ", "๐Ÿ’ฉ", "๐Ÿ’ช", "๐Ÿ’ซ", "๐Ÿ’ฌ", "๐Ÿ’ฎ", "๐Ÿ’ฏ", "๐Ÿ’ฐ", "๐Ÿ’ฑ", "๐Ÿ’ฒ", "๐Ÿ’ณ", "๐Ÿ’ด", "๐Ÿ’ต", "๐Ÿ’ธ", "๐Ÿ’น", "๐Ÿ’บ", "๐Ÿ’ป", "๐Ÿ’ผ", "๐Ÿ’ฝ", "๐Ÿ’พ", "๐Ÿ’ฟ", "๐Ÿ“€", "๐Ÿ“", "๐Ÿ“‚", "๐Ÿ“ƒ", "๐Ÿ“„", "๐Ÿ“…", "๐Ÿ“†", "๐Ÿ“‡", "๐Ÿ“ˆ", "๐Ÿ“‰", "๐Ÿ“Š", "๐Ÿ“‹", "๐Ÿ“Œ", "๐Ÿ“", "๐Ÿ“Ž", "๐Ÿ“", "๐Ÿ“", "๐Ÿ“‘", "๐Ÿ“’", "๐Ÿ““", "๐Ÿ“”", "๐Ÿ“•", "๐Ÿ“–", "๐Ÿ“—", "๐Ÿ“˜", "๐Ÿ“™", "๐Ÿ“š", "๐Ÿ“›", "๐Ÿ“œ", "๐Ÿ“", "๐Ÿ“ž", "๐Ÿ“Ÿ", "๐Ÿ“ ", "๐Ÿ“ก", "๐Ÿ“ข", "๐Ÿ“ฃ", "๐Ÿ“ค", "๐Ÿ“ฅ", "๐Ÿ“ฆ", "๐Ÿ“ง", "๐Ÿ“จ", "๐Ÿ“ฉ", "๐Ÿ“ช", "๐Ÿ“ซ", "๐Ÿ“ฎ", "๐Ÿ“ฐ", "๐Ÿ“ฑ", "๐Ÿ“ฒ", "๐Ÿ“ณ", "๐Ÿ“ด", "๐Ÿ“ถ", "๐Ÿ“ท", "๐Ÿ“น", "๐Ÿ“บ", "๐Ÿ“ป", "๐Ÿ“ผ", "๐Ÿ”ƒ", "๐Ÿ”Š", "๐Ÿ”‹", "๐Ÿ”Œ", "๐Ÿ”", "๐Ÿ”Ž", "๐Ÿ”", "๐Ÿ”", "๐Ÿ”‘", "๐Ÿ”’", "๐Ÿ”“", "๐Ÿ””", "๐Ÿ”–", "๐Ÿ”—", "๐Ÿ”˜", "๐Ÿ”™", "๐Ÿ”š", "๐Ÿ”›", "๐Ÿ”œ", "๐Ÿ”", "๐Ÿ”ž", "๐Ÿ”Ÿ", "๐Ÿ” ", "๐Ÿ”ก", "๐Ÿ”ข", "๐Ÿ”ฃ", "๐Ÿ”ค", "๐Ÿ”ฅ", "๐Ÿ”ฆ", "๐Ÿ”ง", "๐Ÿ”จ", "๐Ÿ”ฉ", "๐Ÿ”ช", "๐Ÿ”ซ", "๐Ÿ”ฎ", "๐Ÿ”ฏ", "๐Ÿ”ฐ", "๐Ÿ”ฑ", "๐Ÿ”ฒ", "๐Ÿ”ณ", "๐Ÿ”ด", "๐Ÿ”ต", "๐Ÿ”ถ", "๐Ÿ”ท", "๐Ÿ”ธ", "๐Ÿ”น", "๐Ÿ”บ", "๐Ÿ”ป", "๐Ÿ”ผ", "๐Ÿ”ฝ", "๐Ÿ•", "๐Ÿ•‘", "๐Ÿ•’", "๐Ÿ•“", "๐Ÿ•”", "๐Ÿ••", "๐Ÿ•–", "๐Ÿ•—", "๐Ÿ•˜", "๐Ÿ•™", "๐Ÿ•š", "๐Ÿ•›", "๐Ÿ—ป", "๐Ÿ—ผ", "๐Ÿ—ฝ", "๐Ÿ—พ", "๐Ÿ—ฟ", "๐Ÿ˜", "๐Ÿ˜‚", "๐Ÿ˜ƒ", "๐Ÿ˜„", "๐Ÿ˜…", "๐Ÿ˜†", "๐Ÿ˜‰", "๐Ÿ˜Š", "๐Ÿ˜‹", "๐Ÿ˜Œ", "๐Ÿ˜", "๐Ÿ˜", "๐Ÿ˜’", "๐Ÿ˜“", "๐Ÿ˜”", "๐Ÿ˜–", "๐Ÿ˜˜", "๐Ÿ˜š", "๐Ÿ˜œ", "๐Ÿ˜", "๐Ÿ˜ž", "๐Ÿ˜ ", "๐Ÿ˜ก", "๐Ÿ˜ข", "๐Ÿ˜ฃ", "๐Ÿ˜ค", "๐Ÿ˜ฅ", "๐Ÿ˜จ", "๐Ÿ˜ฉ", "๐Ÿ˜ช", "๐Ÿ˜ซ", "๐Ÿ˜ญ", "๐Ÿ˜ฐ", "๐Ÿ˜ฑ", "๐Ÿ˜ฒ", "๐Ÿ˜ณ", "๐Ÿ˜ต", "๐Ÿ˜ท", "๐Ÿ˜ธ", "๐Ÿ˜น", "๐Ÿ˜บ", "๐Ÿ˜ป", "๐Ÿ˜ผ", "๐Ÿ˜ฝ", "๐Ÿ˜พ", "๐Ÿ˜ฟ", "๐Ÿ™€", "๐Ÿ™…", "๐Ÿ™†", "๐Ÿ™‡", "๐Ÿ™ˆ", "๐Ÿ™‰", "๐Ÿ™Š", "๐Ÿ™‹", "๐Ÿ™Œ", "๐Ÿ™", "๐Ÿ™Ž", "๐Ÿ™", "๐Ÿš€", "๐Ÿšƒ", "๐Ÿš„", "๐Ÿš…", "๐Ÿš‡", "๐Ÿš‰", "๐ŸšŒ", "๐Ÿš", "๐Ÿš‘", "๐Ÿš’", "๐Ÿš“", "๐Ÿš•", "๐Ÿš—", "๐Ÿš™", "๐Ÿšš", "๐Ÿšข", "๐Ÿšค", "๐Ÿšฅ", "๐Ÿšง", "๐Ÿšจ", "๐Ÿšฉ", "๐Ÿšช", "๐Ÿšซ", "๐Ÿšฌ", "๐Ÿšญ", "๐Ÿšฒ", "๐Ÿšถ", "๐Ÿšน", "๐Ÿšบ", "๐Ÿšป", "๐Ÿšผ", "๐Ÿšฝ", "๐Ÿšพ", "๐Ÿ›€", "๐Ÿ‡ฆ", "๐Ÿ‡ง", "๐Ÿ‡จ", "๐Ÿ‡ฉ", "๐Ÿ‡ช", "๐Ÿ‡ซ", "๐Ÿ‡ฌ", "๐Ÿ‡ญ", "๐Ÿ‡ฎ", "๐Ÿ‡ฏ", "๐Ÿ‡ฐ", "๐Ÿ‡ฑ", "๐Ÿ‡ฒ", "๐Ÿ‡ณ", "๐Ÿ‡ด", "๐Ÿ‡ต", "๐Ÿ‡ถ", "๐Ÿ‡ท", "๐Ÿ‡ธ", "๐Ÿ‡น", "๐Ÿ‡บ", "๐Ÿ‡ป", "๐Ÿ‡ผ", "๐Ÿ‡ฝ", "๐Ÿ‡พ", "๐Ÿ‡ฟ", "๐ŸŒ", "๐ŸŒŽ", "๐ŸŒ", "๐ŸŒ’", "๐ŸŒ–", "๐ŸŒ—", "๎”Š", "ใ€ฐ", "โžฐ", "โž—", "โž–", "โž•", "โ•", "โ”", "โ“", "โŽ", "โŒ", "โœจ", "โœ‹", "โœŠ", "โœ…", "โ›Ž", "โณ", "โฐ", "โฌ", "โซ", "โช", "โฉ", "โ„ข", "โžฟ", "ยฉ", "ยฎ"];
var regenerate = require('regenerate');
var regenerated = regenerate.apply(null, list);
console.log(list.filter(function (chr) {
  return (0 <= chr && chr <= 9) || chr == '#';
}).length ?
  'There should be #0-9 in the RegExp' :
  'There should be NO #0-9 in the RegExp'
);
console.log(regenerated.toRegExp());

This should not result in the following RegExp:

/[#0-9\xA9\xAE\u2122\u23E9-\u23EC\u23F0\u23F3\u26CE\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u3030\uE50A]|\uD83C[\uDCCF\uDD70\uDD71\uDD7E\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF30-\uDF35\uDF37-\uDF7C\uDF80-\uDF93\uDFA0-\uDFC4\uDFC6-\uDFCA\uDFE0-\uDFF0]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCF7\uDCF9-\uDCFC\uDD00-\uDD3D\uDD50-\uDD67\uDDFB-\uDE40\uDE45-\uDE4F\uDE80-\uDEC5]/

'cause #0-9 is absolutely undesired as a match.

Thanks for any sort of outcome.

Donโ€™t move unmatched high surrogates to the end of the regex if itโ€™s not needed

Currently:

// Create a regular expression that matches any BMP code point:
regenerate.fromCodePointRange(0x0000, 0xFFFF);
// โ†’ '[\\0-\\uD7FF\\uDC00-\\uFFFF]|[\\uD800-\\uDBFF]'

Any unmatched high surrogates need to be moved to the end of the regex only if the list of code points includes at least 1 astral symbol. This is not the case in the above example, so (I think) the result could just be:

// Create a regular expression that matches any BMP code point:
regenerate.fromCodePointRange(0x0000, 0xFFFF);
// โ†’ '[\\0-\\uFFFF]'

I might be missing something here, so Iโ€™m hoping someone like @slevithan can double-check this.

Optimize `regenerate.prototype.removeRange`

Ref. #12.

Instead of creating a range in such a case, just convert the arguments to code points (if they arenโ€™t already) and loop over the code points in the set, removing those that are not within the bounds of the range.

`regenerate.fromCodePointRanges` or similar

Make it easier to create regular expressions that consist of a set of ranges:

E.g. when presented with a list like this (taken from http://www.w3.org/TR/turtle/#sec-grammar-grammar):

[A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]

Maybe something like this? (Using different code points than in the above example to keep it simple.)

regenerate.foo([
  '200C',
  'F900-FDCF',
  'FDF0-FFFD',
  '010000-0EFFFF'
]);

Any ideas on how to name such a method (foo in the example), or ideas on what would be a better API are more than welcome :) Perhaps we could overload fromCodePoints at the cost of performance?

isArray is not using the native isArray method, causing incompatibilities with prototype.js

isArray should use the browser's native implementation of isArray if available.
This causes errors when running regenerate together with prototype.js:

symbol.charCodeAt is not a function
	TypeError: symbol.charCodeAt is not a function
	    at symbolToCodePoint (http://localhost:1090/IPdeploy/js/systemjs-babel-browser.js:24493:23)
	    at regenerate.add (http://localhost:1090/IPdeploy/js/systemjs-babel-browser.js:24928:64)
	    at regenerate (http://localhost:1090/IPdeploy/js/systemjs-babel-browser.js:24902:28)
	    at eval (http://localhost:1090/IPdeploy/js/systemjs-babel-browser.js:25033:8)

etareneger - this but the reverse

So regenerate builds a set of characters and can express that set as a simple regex - have you thought about the opposite process of taking a regex and producing a character set?

Reduce file size to use it as a RegExp polyfill

The library size is too big for using it as a polyfill. Maybe you can do something to reduce it side? For example: The polyfill do not need a methods such 'intersection' or 'contains', it's only need a addRange and removeRange.

I tried to make a small version of you library, but it doesn't work as good as the original one. Also it based on old version of regenerate library. But my version is very small - just what I need.

Test more environments

I want to add this to the README:

## Support

Regenerate has been tested in at least Chrome 27-29, Firefox 3-22, Safari 4-6, Opera 10-12, IE 6-10, Node.js v0.10.0, Narwhal 0.3.2, RingoJS 0.8-0.9, and Rhino 1.7RC4.

Letโ€™s make it happen! Environments to test:

  • Chrome 27-29
  • Firefox 3-22
  • Safari 4-6
  • Opera 10-12
  • IE 6-10
  • Node.js v0.10.0
  • Narwhal 0.3.2
  • RingoJS 0.8-0.9
  • Rhino 1.7RC4
  • PhantomJS

The test suite is pretty damn slow, but hey. Testing Rhino can take up to 90 seconds on my machine. Narwhal: 150 seconds.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.