Are you happy with your logging solution? Would you help us out by taking a 30-second survey? Click here

regenerate

Generate JavaScript-compatible regular expressions based on a given set of Unicode symbols or code points.

Subscribe to updates I use regenerate


Statistics on regenerate

Number of watchers on Github 217
Number of open issues 2
Average time to close an issue about 2 months
Main language JavaScript
Average time to merge a PR 5 months
Open pull requests 1+
Closed pull requests 5+
Last commit about 2 years ago
Repo Created over 6 years ago
Repo Last Updated over 1 year ago
Size 264 KB
Homepage https://mths.be/r...
Organization / Authormathiasbynens
Latest Releasev0.6.0
Contributors3
Page Updated
Do you use regenerate? Leave a review!
View open issues (2)
View regenerate activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Trendy new open source projects in your inbox! View examples

Subscribe to our mailing list

Evaluating regenerate for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

Regenerate Build status Code coverage status Dependency status

Regenerate is a Unicode-aware regex generator for JavaScript. It allows you to easily generate ES5-compatible regular expressions based on a given set of Unicode symbols or code points. (This is trickier than you might think, because of how JavaScript deals with astral symbols.)

Installation

Via npm:

npm install regenerate

Via Bower:

bower install regenerate

Via Component:

component install mathiasbynens/regenerate

In a browser:

<script src="regenerate.js"></script>

In Node.js, io.js, and RingoJS v0.8.0:

var regenerate = require('regenerate');

In Narwhal and RingoJS v0.7.0:

var regenerate = require('regenerate').regenerate;

In Rhino:

load('regenerate.js');

Using an AMD loader like RequireJS:

require(
  {
    'paths': {
      'regenerate': 'path/to/regenerate'
    }
  },
  ['regenerate'],
  function(regenerate) {
    console.log(regenerate);
  }
);

API

regenerate(value1, value2, value3, ...)

The main Regenerate function. Calling this function creates a new set that gets a chainable API.

var set = regenerate()
  .addRange(0x60, 0x69) // add U+0060 to U+0069
  .remove(0x62, 0x64) // remove U+0062 and U+0064
  .add(0x1D306); // add U+1D306
set.valueOf();
//  [0x60, 0x61, 0x63, 0x65, 0x66, 0x67, 0x68, 0x69, 0x1D306]
set.toString();
//  '[`ace-i]|\\uD834\\uDF06'
set.toRegExp();
//  /[`ace-i]|\uD834\uDF06/

Any arguments passed to regenerate() will be added to the set right away. Both code points (numbers) and symbols (strings consisting of a single Unicode symbol) are accepted, as well as arrays containing values of these types.

regenerate(0x1D306, 'A', '', 0x2603).toString();
//  '[A\\xA9\\u2603]|\\uD834\\uDF06'

var items = [0x1D306, 'A', '', 0x2603];
regenerate(items).toString();
//  '[A\\xA9\\u2603]|\\uD834\\uDF06'

regenerate.prototype.add(value1, value2, value3, ...)

Any arguments passed to add() are added to the set. Both code points (numbers) and symbols (strings consisting of a single Unicode symbol) are accepted, as well as arrays containing values of these types.

regenerate().add(0x1D306, 'A', '', 0x2603).toString();
//  '[A\\xA9\\u2603]|\\uD834\\uDF06'

var items = [0x1D306, 'A', '', 0x2603];
regenerate().add(items).toString();
//  '[A\\xA9\\u2603]|\\uD834\\uDF06'

Its also possible to pass in a Regenerate instance. Doing so adds all code points in that instance to the current set.

var set = regenerate(0x1D306, 'A');
regenerate().add('', 0x2603).add(set).toString();
//  '[A\\xA9\\u2603]|\\uD834\\uDF06'

Note that the initial call to regenerate() acts like add(). This allows you to create a new Regenerate instance and add some code points to it in one go:

regenerate(0x1D306, 'A', '', 0x2603).toString();
//  '[A\\xA9\\u2603]|\\uD834\\uDF06'

regenerate.prototype.remove(value1, value2, value3, ...)

Any arguments passed to remove() are removed to the set. Both code points (numbers) and symbols (strings consisting of a single Unicode symbol) are accepted, as well as arrays containing values of these types.

regenerate(0x1D306, 'A', '', 0x2603).remove('').toString();
//  '[A\\xA9]|\\uD834\\uDF06'

Its also possible to pass in a Regenerate instance. Doing so removes all code points in that instance from the current set.

var set = regenerate('');
regenerate(0x1D306, 'A', '', 0x2603).remove(set).toString();
//  '[A\\xA9]|\\uD834\\uDF06'

regenerate.prototype.addRange(start, end)

Adds a range of code points from start to end (inclusive) to the set. Both code points (numbers) and symbols (strings consisting of a single Unicode symbol) are accepted.

regenerate(0x1D306).addRange(0x00, 0xFF).toString(16);
//  '[\\0-\\xFF]|\\uD834\\uDF06'

regenerate().addRange('A', 'z').toString();
//  '[A-z]'

regenerate.prototype.removeRange(start, end)

Removes a range of code points from start to end (inclusive) from the set. Both code points (numbers) and symbols (strings consisting of a single Unicode symbol) are accepted.

regenerate()
  .addRange(0x000000, 0x10FFFF) // add all Unicode code points
  .removeRange('A', 'z') // remove all symbols from `A` to `z`
  .toString();
//  '[\\0-@\\{-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]'

regenerate()
  .addRange(0x000000, 0x10FFFF) // add all Unicode code points
  .removeRange(0x0041, 0x007A) // remove all code points from U+0041 to U+007A
  .toString();
//  '[\\0-@\\{-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]'

regenerate.prototype.intersection(codePoints)

Removes any code points from the set that are not present in both the set and the given codePoints array. codePoints must be an array of numeric code point values, i.e. numbers.

regenerate()
  .addRange(0x00, 0xFF) // add extended ASCII code points
  .intersection([0x61, 0x69]) // remove all code points from the set except for these
  .toString();
//  '[ai]'

Instead of the codePoints array, its also possible to pass in a Regenerate instance.

var whitelist = regenerate(0x61, 0x69);

regenerate()
  .addRange(0x00, 0xFF) // add extended ASCII code points
  .intersection(whitelist) // remove all code points from the set except for those in the `whitelist` set
  .toString();
//  '[ai]'

regenerate.prototype.contains(value)

Returns true if the given value is part of the set, and false otherwise. Both code points (numbers) and symbols (strings consisting of a single Unicode symbol) are accepted.

var set = regenerate().addRange(0x00, 0xFF);
set.contains('A');
//  true
set.contains(0x1D306);
//  false

regenerate.prototype.clone()

Returns a clone of the current code point set. Any actions performed on the clone wont mutate the original set.

var setA = regenerate(0x1D306);
var setB = setA.clone().add(0x1F4A9);
setA.toArray();
//  [0x1D306]
setB.toArray();
//  [0x1D306, 0x1F4A9]

regenerate.prototype.toString(options)

Returns a string representing (part of) a regular expression that matches all the symbols mapped to the code points within the set.

regenerate(0x1D306, 0x1F4A9).toString();
//  '\\uD834\\uDF06|\\uD83D\\uDCA9'

If the bmpOnly property of the optional options object is set to true, the output matches surrogates individually, regardless of whether theyre lone surrogates or just part of a surrogate pair. This simplifies the output, but it can only be used in case youre certain the strings it will be used on dont contain any astral symbols.

var highSurrogates = regenerate().addRange(0xD800, 0xDBFF);
highSurrogates.toString();
//  '[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])'
highSurrogates.toString({ 'bmpOnly': true });
//  '[\\uD800-\\uDBFF]'

var lowSurrogates = regenerate().addRange(0xDC00, 0xDFFF);
lowSurrogates.toString();
//  '(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]'
lowSurrogates.toString({ 'bmpOnly': true });
//  '[\\uDC00-\\uDFFF]'

Note that lone low surrogates cannot be matched accurately using regular expressions in JavaScript. Regenerates output makes a best-effort approach but there can be false negatives in this regard.

If the hasUnicodeFlag property of the optional options object is set to true, the output makes use of Unicode code point escapes (\u{}) where applicable. This simplifies the output at the cost of compatibility and portability, since it means the output can only be used as a pattern in a regular expression with the ES6 u flag enabled.

var set = regenerate().addRange(0x0, 0x10FFFF);

set.toString();
//  '[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]''

set.toString({ 'hasUnicodeFlag': true });
//  '[\\0-\\u{10FFFF}]'

regenerate.prototype.toRegExp(flags = '')

Returns a regular expression that matches all the symbols mapped to the code points within the set. Optionally, you can pass flags to be added to the regular expression.

var regex = regenerate(0x1D306, 0x1F4A9).toRegExp();
//  /\uD834\uDF06|\uD83D\uDCA9/
regex.test('');
//  true
regex.test('A');
//  false

// With flags:
var regex = regenerate(0x1D306, 0x1F4A9).toRegExp('g');
//  /\uD834\uDF06|\uD83D\uDCA9/g

Note: This probably shouldnt be used. Regenerate is intended as a tool that is used as part of a build process, not at runtime.

regenerate.prototype.valueOf() or regenerate.prototype.toArray()

Returns a sorted array of unique code points in the set.

regenerate(0x1D306)
  .addRange(0x60, 0x65)
  .add(0x59, 0x60) // note: 0x59 is added after 0x65, and 0x60 is a duplicate
  .valueOf();
//  [0x59, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x1D306]

regenerate.version

A string representing the semantic version number.

Combine Regenerate with other libraries

Regenerate gets even better when combined with other libraries such as Punycode.js. Heres an example where Punycode.js is used to convert a string into an array of code points, that is then passed on to Regenerate:

var regenerate = require('regenerate');
var punycode = require('punycode');

var string = 'Lorem ipsum dolor sit amet.';
// Get an array of all code points used in the string:
var codePoints = punycode.ucs2.decode(string);

// Generate a regular expression that matches any of the symbols used in the string:
regenerate(codePoints).toString();
//  '[ \\.Ladeilmopr-u]'

In ES6 you can do something similar with Array.from which uses the strings iterator to split the given string into an array of strings that each contain a single symbol. regenerate() accepts both strings and code points, remember?

var regenerate = require('regenerate');

var string = 'Lorem ipsum dolor sit amet.';
// Get an array of all symbols used in the string:
var symbols = Array.from(string);

// Generate a regular expression that matches any of the symbols used in the string:
regenerate(symbols).toString();
//  '[ \\.Ladeilmopr-u]'

Support

Regenerate supports at least Chrome 27+, Firefox 3+, Safari 4+, Opera 10+, IE 6+, Node.js v0.10.0+, io.js v1.0.0+, Narwhal 0.3.2+, RingoJS 0.8+, PhantomJS 1.9.0+, and Rhino 1.7RC4+.

Unit tests & code coverage

After cloning this repository, run npm install to install the dependencies needed for Regenerate development and testing. You may want to install Istanbul globally using npm install istanbul -g.

Once thats done, you can run the unit tests in Node using npm test or node tests/tests.js. To run the tests in Rhino, Ringo, Narwhal, and web browsers as well, use grunt test.

To generate the code coverage report, use grunt cover.

Author

twitter/mathias
Mathias Bynens

License

Regenerate is available under the MIT license.

regenerate open issues Ask a question     (View All Issues)
  • over 5 years Write a fuzzer to try and find more bugs
  • over 6 years Enable continuous integration for browsers using Testling
regenerate open pull requests (View All Pulls)
  • bug #32: isArray is not using native isArray
regenerate questions on Stackoverflow (View All Questions)
  • How do I regenerate imagecache thumbnails in drupal 6?
  • Can you regenerate a deleted modules .iml file in android studio
  • MongoDB regenerate .ns file
  • Is their a way to regenerate the push notification token manually (iOS, Android, Windows)
  • ios Provisioning profile regenerate
  • Missing csproj file - Recreate/regenerate one
  • How to regenerate laravel Session id
  • How use pcode to regenerate a file in MatLab?
  • do i have to regenerate wsdl after changing the webservice method
  • How to regenerate SQL scripts by Play Slick Evolution
  • How do you force Visual Studio to regenerate the .designer files for aspx/ascx files?
  • Regenerate NSManagedObject subclasses on build
  • Regenerate SessionIds in Laravel 5.2
  • android studio: how to regenerate build.gradle
  • Tomcat / JKS / Keytool - regenerate private key?
  • My R.java file is removed after fabric.io installation.How can I regenerate it?
  • How to regenerate crud -- doctrine:generate:crud after editing the entity
  • How to reGENERATE random number?
  • Is there a way to regenerate a missing .resx file?
  • Auto compilation of bootstrap less file with gulp/gulp-watch-less does'nt regenerate the css
  • Did Windows really just spontaneously regenerate my ssh key for git?
  • How to solve "session_regenerate_id(): Cannot regenerate session id - headers already sent"
  • Getting error while Regenerate Application AccessToken using Curl command in wso2 API manager 1.8.0
  • iOS: if I regenerate provisioning profile after adding a new capability, what will happen to an existing APNS capability?
  • Regenerate .CS files from gui.stetic
  • How to regenerate Team Provisioning Profile?
  • How to regenerate a token when cookie has expired
  • Orchard CMS Update/Regenerate Permalinks after autoroute update
  • "jekyll serve --watch" doesn't regenerate automatically
  • Is there a way to regenerate an identityId in AWS Cognito for the given device?
regenerate list of languages used
regenerate latest release notes

Regenerate v0.6.0 is much more memory-efficient and faster than v0.5.4. Internally, it was completely rewritten based on a new data structure to store the set of code points in. As a result, the code is not as readable as it used to be, but the performance improvement is worth it. Heres an example, where I ran https://gist.github.com/mathiasbynens/6334847 using both versions:

$ time node javascript-identifier-regex.js > /dev/null # using Regenerate v0.5.4

real    0m5.867s
user    0m5.837s
sys 0m0.077s

$ time node javascript-identifier-regex.js > /dev/null # using Regenerate v0.6.0

real    0m0.440s
user    0m0.419s
sys 0m0.023s

API changes

  • The non-chaining API has been removed. Use the chaining API instead.
  • New method: regenerate.prototype.clone().
  • More single-character escape sequences are now used, resulting in more compact output.
  • Methods are now exposed on regenerate.prototype, which enables you to create your own Regenerate plugins. See #20 for an example.
  • add, remove, difference, and intersection now accept other Regenerate instances as arguments.
Other projects in JavaScript