Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: slevithan/xregexp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.1.1
Choose a base ref
...
head repository: slevithan/xregexp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.2.0
Choose a head ref

Commits on May 15, 2016

  1. Copy the full SHA
    63273f9 View commit details

Commits on Jul 19, 2016

  1. Correctly escape closing square brackets in two regular expression li…

    …terals.
    
    The Duktape JavaScript engine is very strict when it comes to regex literals.
    It was choking on two regexs in the XRegExp source. This commit correctly escapes
    two closing square brackets that should be escaped because they don't have an opening
    counterpart and they should be matched as a literal character.
    jfahrenkrug committed Jul 19, 2016
    Copy the full SHA
    f5dbc86 View commit details

Commits on Jul 20, 2016

  1. Merge pull request #141 from jfahrenkrug/escape_regex_square_brackets

    Correctly escape closing square brackets in two regular expression literals
    slevithan authored Jul 20, 2016
    Copy the full SHA
    ac800e6 View commit details

Commits on Aug 7, 2016

  1. typo fix in comment

    GerHobbelt committed Aug 7, 2016
    Copy the full SHA
    5329cbf View commit details
  2. follow-up on commit SHA-1: f5dbc86 (:: Correctly escape closing squar…

    …e brackets in two regular expression literals.) --> one more regex with an escaped = *literal* square bracket.
    GerHobbelt committed Aug 7, 2016
    Copy the full SHA
    0a58dd3 View commit details
  3. migrated performance tests to use latest BenchmarkJS v2.1.1 (which re…

    …quires lodash and optional platform libraries to be loaded as well: these are included in the tests/vendor/benchmark.js/ directory)
    GerHobbelt committed Aug 7, 2016
    Copy the full SHA
    00ba16a View commit details

Commits on Aug 10, 2016

  1. Merge pull request #142 from GerHobbelt/patch-typo-fix-1

    typo fix in comment
    slevithan authored Aug 10, 2016
    Copy the full SHA
    1f65356 View commit details

Commits on Aug 29, 2016

  1. Merge pull request #143 from GerHobbelt/patch-literal-brackets-followup

    follow-up on commit SHA-1: f5dbc86 (escaping literal brackets)
    slevithan authored Aug 29, 2016
    Copy the full SHA
    7da5445 View commit details
  2. Merge pull request #145 from GerHobbelt/patch-perf-tests-upgrade

    migrated performance tests to use latest BenchmarkJS v2.1.1
    slevithan authored Aug 29, 2016
    Copy the full SHA
    dbbceb3 View commit details
  3. Rebuild xregexp-all

    slevithan committed Aug 29, 2016
    Copy the full SHA
    5a7702d View commit details
  4. Copy the full SHA
    bb4c55c View commit details

Commits on Sep 11, 2016

  1. completed JSDoc et al documentation markup with @private and `@memb…

    …erOf` tags for XRegExp and (obsoleted) natives overrides by XRegExp.
    GerHobbelt committed Sep 11, 2016
    Copy the full SHA
    ce6dc9a View commit details
  2. comment typo fix

    GerHobbelt committed Sep 11, 2016
    Copy the full SHA
    8c8d44d View commit details

Commits on Sep 12, 2016

  1. Merge pull request #148 from GerHobbelt/patch-comment-typo

    comment typo fix
    slevithan authored Sep 12, 2016
    Copy the full SHA
    f9df99c View commit details

Commits on Feb 2, 2017

  1. Added API XRegExp._getUnicodeProperty(name)

    * added API `XRegExp.isUnicodeSlug(name)` which checks whether a given `name` is a recognized Unicode Slug, e.g. `Number` (but not `Numeric` as `\p{Numeric}` is an *invalid* Unicode `\p` regex slug.  This API is used by the GerHobbelt/jison app to help add Unicode support to the grammars being compiled. The way the API internals (**and documentation**, see the comment block in the patch) is written, i.e. that rather than a plain `true` boolean value, a 'truthy' Unicode slug definition is produced, is also used by the GerHobbelt/jison app: that code generator uses this artifact to greatly simplify lexer regex expansion and rewriting.
    
    * (Cherrypick) Following comments in #144, adjust the code to rename the API to `_getUnicodeProperty` -- I also went and checked the official term for these 'slugs': as I intend them, they're called 'categories' or 'Unicode Properties' (http://unicode.org/reports/tr18/#Categories)
    
    # Conflicts:
    #	src/addons/unicode-base.js
    #	xregexp-all.js
    GerHobbelt authored and slevithan committed Feb 2, 2017
    Copy the full SHA
    8649ac6 View commit details

Commits on Feb 7, 2017

  1. build

    pygy committed Feb 7, 2017
    Copy the full SHA
    e711b63 View commit details
  2. Optimize sticky matching.

    pygy committed Feb 7, 2017
    Copy the full SHA
    33f1998 View commit details
  3. build

    pygy committed Feb 7, 2017
    Copy the full SHA
    f01fe73 View commit details

Commits on Feb 8, 2017

  1. Merge pull request #153 from pygy/fast-fake-y

    Optimize sticky matching
    slevithan authored Feb 8, 2017
    Copy the full SHA
    3378790 View commit details
  2. Merge pull request #147 from GerHobbelt/patch-jsdoc-tagging

    completed JSDoc et al documentation markup
    slevithan authored Feb 8, 2017
    Copy the full SHA
    741cf08 View commit details
  3. Tweaks

    unknown authored and unknown committed Feb 8, 2017
    Copy the full SHA
    42d494e View commit details

Commits on Feb 12, 2017

  1. Don't allocate the sticky regex source when the resulting regexp is a…

    …lready cached (#154)
    
    * Fast sticky polyfill: don't allocate the new source when the polyfilled expression is already cached
    
    * build
    pygy authored and slevithan committed Feb 12, 2017
    Copy the full SHA
    065de70 View commit details

Commits on Feb 14, 2017

  1. Add test script

    This makes it easier for new developers to run the tests, by typing `npm
    test`. This will build `xregexp-all.js`, then open `tests/index.html` in a
    browser, using [opener].
    
    [opener]: https://www.npmjs.com/package/opener
    josephfrazier committed Feb 14, 2017
    Copy the full SHA
    39d8266 View commit details
  2. Add max_line_length to .editorconfig

    It looks like comments have manually been wrapped to 100 characters, so
    use that as the [max_line_length] in the .editorconfig file.
    
    [max_line_length]: https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#max_line_length
    josephfrazier committed Feb 14, 2017
    Copy the full SHA
    5c04038 View commit details
  3. Merge pull request #156 from josephfrazier/editorconfig-max_line_length

    Add max_line_length to .editorconfig
    slevithan authored Feb 14, 2017
    Copy the full SHA
    62e1998 View commit details
  4. Merge pull request #155 from josephfrazier/test

    Add test script
    slevithan authored Feb 14, 2017
    Copy the full SHA
    befc05d View commit details
  5. Make tests run in Node

    This is a follow-up to
    #155 (comment)
    that lets the tests run in Node, without opening a browser. It's set up
    so that opening tests/index.html still works, for anyone who prefers
    that workflow.
    
    See the jasmine docs for more info on using it with Node: https://jasmine.github.io/2.5/node.html
    josephfrazier committed Feb 14, 2017
    Copy the full SHA
    8a5eaf1 View commit details
  6. Merge pull request #159 from josephfrazier/test-node

    Make tests run in Node
    slevithan authored Feb 14, 2017
    Copy the full SHA
    2b65288 View commit details
  7. .editorconfig: Set *.yml indent_size to 2

    This is the convention for .travis.yml files.
    josephfrazier committed Feb 14, 2017
    Copy the full SHA
    1921402 View commit details
  8. Copy the full SHA
    5549ac6 View commit details
  9. Copy the full SHA
    99bfd0b View commit details

Commits on Mar 23, 2017

  1. Merge pull request #160 from josephfrazier/travis

    Add Travis CI configuration
    slevithan authored Mar 23, 2017
    Copy the full SHA
    56ccef1 View commit details
  2. Pass XRegExp.build flags through asXRegExp to XRegExp constructor (#163)

    Work around Firefox issue where '\n' is not ignored with flag x when used with XRegExp.build. See #163.
    josephfrazier authored and slevithan committed Mar 23, 2017
    Copy the full SHA
    c1629b8 View commit details

Commits on Mar 24, 2017

  1. Tweaks

    slevithan committed Mar 24, 2017
    Copy the full SHA
    7923d35 View commit details

Commits on Mar 28, 2017

  1. Use subpatterns in isQuantifierNext

    This doesn't change its behavior, but makes it more readable and easier
    to modify.
    josephfrazier committed Mar 28, 2017
    Copy the full SHA
    cddec76 View commit details
  2. Extract isPatternNext helper from isQuantifierNext

    This will allow us to use it for matching other patterns than just
    quantifiers.
    josephfrazier committed Mar 28, 2017
    Copy the full SHA
    6ec37f8 View commit details
  3. Test that XRegExp should not put (?:) at beginning/end of groups

    This test currently fails. Here's the actual and expected patterns, with
    whitespace inserted to illustrate the difference:
    
    '((?:)[0-9]{4}(?:))(?:)-?(?:)((?:)[0-9]{2}(?:))(?:)-?(?:)((?:)[0-9]{2}(?:))(?:)'
    '(    [0-9]{4}    )(?:)-?(?:)(    [0-9]{2}    )(?:)-?(?:)(    [0-9]{2}    )(?:)'
    josephfrazier committed Mar 28, 2017
    Copy the full SHA
    605397b View commit details
  4. Don't insert (?:) at the beginning/end of a group

    This passes the tests in the previous commit, using the new
    isPatternNext function to determine if the match is at the end of a
    group.
    
    Checking if the match is at the beginning of a group is a little
    more naive, since it only looks at the previous character, rather than
    ignoring comments and whitespace, but I haven't found a good way to
    improve on that.
    josephfrazier committed Mar 28, 2017
    Copy the full SHA
    c41d699 View commit details
  5. Extract getCommentOrWhitespace helper from token handlers

    I realized the token handlers are equivalent, so I made them a named
    function instead.
    josephfrazier committed Mar 28, 2017
    Copy the full SHA
    68abf55 View commit details
  6. fixup! Extract isPatternNext helper from isQuantifierNext

    Use `new` with RegExp constructor, as is done everywhere else.
    josephfrazier committed Mar 28, 2017
    Copy the full SHA
    5d8716e View commit details

Commits on Apr 4, 2017

  1. Include build package in package.json for npm installs. (#167)

    * Include build package in package.json for npm installs.
    
    * Update main to point to distribution build. Include LICENSE in files for npm installs.
    kaidjohnson authored and slevithan committed Apr 4, 2017
    Copy the full SHA
    3874365 View commit details

Commits on Apr 10, 2017

  1. Revert "Work around bug in Safari Technology Preview /y support -- cl…

    …oses #135" (#168)
    
    Closes #158
    
    This reverts commit 660f3ac.
    josephfrazier authored and slevithan committed Apr 10, 2017
    Copy the full SHA
    d21c7f7 View commit details
  2. Add conjunction option for XRegExp.union and allow setting to 'none' (

    #169)
    
    The `XRegExp.union` calls in the `build` and `matchRecursive` addons are
    also updated to explicitly specify `{conjunction: 'or'}`.
    
    Fixes #106
    josephfrazier authored and slevithan committed Apr 10, 2017
    Copy the full SHA
    e2010f4 View commit details
  3. Copy the full SHA
    4eb3d64 View commit details
  4. 2016 -> 2017

    slevithan committed Apr 10, 2017
    Copy the full SHA
    a5e5f43 View commit details

Commits on Apr 15, 2017

  1. Change <li>s to hyphens in code comments (#173)

    As seen in #107:
    
    > * Change `<li>`s to asterisks or hyphens in code comments.
    
    I used hyphens rather than asterisks because each comment line already
    starts with an asterisk, so hyphens visually stand out more.
    josephfrazier authored and slevithan committed Apr 15, 2017
    Copy the full SHA
    752feb9 View commit details
  2. Declare each var on a separate line (#172)

    * Declare each `var` on a separate line
    
    This partially addresses the following item in #107:
    
    > * New `var` on each line, and don't always declare vars at top of
    function.
    
    The change was made with the help of [lebab], by running:
    
        lebab --replace src --transform multi-var
    
    [lebab]: https://github.com/lebab/lebab
    
    * Remove blank lines from `var` declarations
    
    See #172 (review)
    josephfrazier authored and slevithan committed Apr 15, 2017
    Copy the full SHA
    db7bd22 View commit details

Commits on Apr 16, 2017

  1. Merge pull request #164 from josephfrazier/strip-useless-groups

    Cleanup (?:) from beginning/end of groups
    slevithan authored Apr 16, 2017
    Copy the full SHA
    cd0d192 View commit details
  2. Copy the full SHA
    7fc4fce View commit details
  3. Copy the full SHA
    622aaf3 View commit details
Showing with 27,912 additions and 4,506 deletions.
  1. +4 −0 .editorconfig
  2. +3 −0 .travis.yml
  3. +1 −1 LICENSE
  4. +30 −31 README.md
  5. +1 −1 bower.json
  6. +10 −5 package.json
  7. +44 −37 src/addons/build.js
  8. +31 −20 src/addons/matchrecursive.js
  9. +60 −27 src/addons/unicode-base.js
  10. +50 −6 src/addons/unicode-blocks.js
  11. +38 −38 src/addons/unicode-categories.js
  12. +11 −11 src/addons/unicode-properties.js
  13. +45 −19 src/addons/unicode-scripts.js
  14. +221 −134 src/xregexp.js
  15. +4 −1 tests/helpers/h-unicode.js
  16. +11 −5 tests/helpers/h.js
  17. +11 −0 tests/jasmine.json
  18. +3 −0 tests/perf/index.html
  19. +94 −75 tests/perf/perf.js
  20. +4,652 −0 tests/perf/versions/xregexp-all-v3.2.0.js
  21. +6 −0 tests/spec/s-addons-build.js
  22. +31 −0 tests/spec/s-xregexp-methods.js
  23. +24 −1 tests/spec/s-xregexp.js
  24. +1 −1 tests/vendor/benchmark.js/LICENSE.txt
  25. +45 −76 tests/vendor/benchmark.js/README.md
  26. +2,447 −3,521 tests/vendor/benchmark.js/benchmark.js
  27. +16,591 −0 tests/vendor/benchmark.js/lodash.js
  28. +1,135 −0 tests/vendor/benchmark.js/platform.js
  29. +15 −4 tools/data/{8.0.0-blocks.txt → 9.0.0-blocks.txt}
  30. +1,380 −3 tools/data/{8.0.0-database.txt → 9.0.0-database.txt}
  31. +138 −84 tools/data/{8.0.0-proplist.txt → 9.0.0-proplist.txt}
  32. +125 −32 tools/data/{8.0.0-scripts.txt → 9.0.0-scripts.txt}
  33. +1 −1 tools/generate-unicode.sh
  34. +47 −3 tools/output/blocks.js
  35. +35 −35 tools/output/categories.js
  36. +8 −8 tools/output/properties.js
  37. +42 −16 tools/output/scripts.js
  38. +2 −2 tools/scripts/block-regex.py
  39. +2 −2 tools/scripts/category-regex.py
  40. +7 −7 tools/scripts/property-regex.py
  41. +2 −2 tools/scripts/script-regex.py
  42. +4 −5 tools/scripts/utils.py
  43. +500 −292 xregexp-all.js
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -7,3 +7,7 @@ indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 100

[*.yml]
indent_size = 2
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
language: node_js
node_js:
- node
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License

Copyright (c) 2007-2016 Steven Levithan <http://xregexp.com/>
Copyright (c) 2007-2017 Steven Levithan <http://xregexp.com/>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
61 changes: 30 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
[XRegExp](http://xregexp.com/) 3.1.1
====================================
# XRegExp 3.2.0

XRegExp provides augmented (and extensible) JavaScript regular expressions. You get new modern syntax and flags beyond what browsers support natively. XRegExp is also a regex utility belt with tools to make your client-side grepping and parsing easier, while freeing you from worrying about pesky aspects of JavaScript regexes like cross-browser inconsistencies or manually manipulating `lastIndex`.
[![Build Status](https://travis-ci.org/slevithan/xregexp.svg?branch=master)](https://travis-ci.org/slevithan/xregexp)

XRegExp supports all native ES6 regular expression syntax. It supports Internet Explorer 5.5+, Firefox 1.5+, Chrome, Safari 3+, and Opera 11+. You can also use it with Node.js or as a RequireJS module.
XRegExp provides augmented (and extensible) JavaScript regular expressions. You get modern syntax and flags beyond what browsers support natively. XRegExp is also a regex utility belt with tools to make your grepping and parsing easier, while freeing you from regex cross-browser inconsistencies and other annoyances.

XRegExp supports all native ES6 regular expression syntax. It supports Internet Explorer 5.5+, Firefox 1.5+, Chrome, Safari 3+, and Opera 11+. You can use it with Node.js or as a RequireJS module.

## Performance

XRegExp regexes compile to native `RegExp` objects, and therefore perform just as fast as native regular expressions. There is a tiny extra cost when compiling a pattern for the first time.
XRegExp compiles to native `RegExp` objects. Therefore regexes built with XRegExp perform just as fast as native regular expressions. There is a tiny extra cost when compiling a pattern for the first time.

## Usage examples

```js
// Using named capture and flag x (free-spacing and line comments)
var date = XRegExp('(?<year> [0-9]{4} ) -? # year \n\
(?<month> [0-9]{2} ) -? # month \n\
(?<day> [0-9]{2} ) # day ', 'x');
var date = XRegExp(`(?<year> [0-9]{4} ) -? # year
(?<month> [0-9]{2} ) -? # month
(?<day> [0-9]{2} ) # day`, 'x');

// XRegExp.exec gives you named backreferences on the match result
var match = XRegExp.exec('2015-02-22', date);
match.year; // -> '2015'
var match = XRegExp.exec('2017-02-22', date);
match.year; // -> '2017'

// It also includes optional pos and sticky arguments
var pos = 3;
@@ -31,31 +32,31 @@ while (match = XRegExp.exec('<1><2><3><4>5<6>', /<(\d+)>/, pos, 'sticky')) {
// result -> ['2', '3', '4']

// XRegExp.replace allows named backreferences in replacements
XRegExp.replace('2015-02-22', date, '${month}/${day}/${year}');
// -> '02/22/2015'
XRegExp.replace('2015-02-22', date, function(match) {
XRegExp.replace('2017-02-22', date, '${month}/${day}/${year}');
// -> '02/22/2017'
XRegExp.replace('2017-02-22', date, (match) => {
return match.month + '/' + match.day + '/' + match.year;
});
// -> '02/22/2015'
// -> '02/22/2017'

// In fact, XRegExps compile to RegExps and work perfectly with native methods
date.test('2015-02-22');
// XRegExps compile to RegExps and work perfectly with native methods
date.test('2017-02-22');
// -> true

// The only caveat is that named captures must be referenced using numbered
// backreferences if used with native methods
'2015-02-22'.replace(date, '$2/$3/$1');
// -> '02/22/2015'
'2017-02-22'.replace(date, '$2/$3/$1');
// -> '02/22/2017'

// Extract every other digit from a string using XRegExp.forEach
// Use XRegExp.forEach to extract every other digit from a string
var evens = [];
XRegExp.forEach('1a2345', /\d/, function(match, i) {
XRegExp.forEach('1a2345', /\d/, (match, i) => {
if (i % 2) evens.push(+match[0]);
});
// evens -> [2, 4]

// Get numbers within <b> tags using XRegExp.matchChain
XRegExp.matchChain('1 <b>2</b> 3 <b>4 a 56</b>', [
// Use XRegExp.matchChain to get numbers within <b> tags
XRegExp.matchChain('1 <b>2</b> 3 <B>4 \n 56</B>', [
XRegExp('(?is)<b>.*?</b>'),
/\d+/
]);
@@ -71,11 +72,11 @@ XRegExp.matchChain(html, [
// -> ['xregexp.com', 'www.google.com']

// Merge strings and regexes into a single pattern with updated backreferences
XRegExp.union(['a+b*c', /(dog)\1/, /(cat)\1/], 'i');
XRegExp.union(['a+b*c', /(dog)\1/, /(cat)\1/], 'i', {conjunction: 'or'});
// -> /a\+b\*c|(dog)\1|(cat)\2/i
```

These examples give the flavor of what's possible, but XRegExp has more syntax, flags, methods, options, and browser fixes that aren't shown here. You can even augment XRegExp's regular expression syntax with addons (see below) or write your own. See [xregexp.com](http://xregexp.com/) for details.
These examples give the flavor of what's possible, but XRegExp has more syntax, flags, methods, options, and browser fixes that aren't shown here. You can also augment XRegExp's regular expression syntax with addons (see below) or write your own. See [xregexp.com](http://xregexp.com/) for details.

## Addons

@@ -99,7 +100,7 @@ XRegExp('^\\p{Hiragana}+$').test('ひらがな'); // -> true
XRegExp('^[\\p{Latin}\\p{Common}]+$').test('Über Café.'); // -> true
```

By default, `\p{…}` and `\P{…}` support the Basic Multilingual Plane (i.e. code points up to `U+FFFF`). You can opt-in to full 21-bit Unicode support (with code points up to `U+10FFFF`) on a per-regex basis by using flag `A`. In XRegExp, this is called *astral mode*. You can automatically add flag `A` for all new regexes by running `XRegExp.install('astral')`. When in astral mode, `\p{…}` and `\P{…}` always match a full code point rather than a code unit, using surrogate pairs for code points above `U+FFFF`.
By default, `\p{…}` and `\P{…}` support the Basic Multilingual Plane (i.e. code points up to `U+FFFF`). You can opt-in to full 21-bit Unicode support (with code points up to `U+10FFFF`) on a per-regex basis by using flag `A`. This is called *astral mode*. You can automatically add flag `A` for all new regexes by running `XRegExp.install('astral')`. When in astral mode, `\p{…}` and `\P{…}` always match a full code point rather than a code unit, using surrogate pairs for code points above `U+FFFF`.

```js
// Using flag A to match astral code points
@@ -116,7 +117,7 @@ XRegExp('^\\pS$').test('💩'); // -> true

Opting in to astral mode disables the use of `\p{…}` and `\P{…}` within character classes. In astral mode, use e.g. `(\pL|[0-9_])+` instead of `[\pL0-9_]+`.

XRegExp uses Unicode 8.0.0.
XRegExp uses Unicode 9.0.0.

### XRegExp.build

@@ -205,17 +206,15 @@ var XRegExp = require('xregexp');
In an AMD loader like [RequireJS](http://requirejs.org/):

```js
require({paths: {xregexp: 'xregexp-all'}}, ['xregexp'], function(XRegExp) {
require({paths: {xregexp: 'xregexp-all'}}, ['xregexp'], (XRegExp) => {
console.log(XRegExp.version);
});
```

## About

XRegExp copyright 2007-2016 by [Steven Levithan](http://stevenlevithan.com/).

Unicode range generators by [Mathias Bynens](http://mathiasbynens.be/), and adapted from his [unicode-data](https://github.com/mathiasbynens/unicode-data) project. Uses [Jasmine](http://jasmine.github.io/) for unit tests, and [Benchmark.js](http://benchmarkjs.com) for performance tests. `XRegExp.build` inspired by [RegExp.create](http://lea.verou.me/2011/03/create-complex-regexps-more-easily/) by [Lea Verou](http://lea.verou.me/). `XRegExp.union` inspired by [Ruby](http://www.ruby-lang.org/). XRegExp's syntax extensions and flags come from [Perl](http://www.perl.org/), [.NET](http://www.microsoft.com/net), etc.
XRegExp copyright 2007-2017 by [Steven Levithan](http://stevenlevithan.com/). Unicode data generators by [Mathias Bynens](http://mathiasbynens.be/), adapted from [unicode-data](http://git.io/unicode). XRegExp's syntax extensions and flags come from [Perl](http://www.perl.org/), [.NET](http://www.microsoft.com/net), etc.

All code, including addons, tools, and tests, is released under the terms of the [MIT License](http://mit-license.org/).

Fork me to show support, fix, and extend.
Learn more at [xregexp.com](http://xregexp.com/).
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "xregexp",
"version": "3.1.1",
"version": "3.2.0",
"description": "Extended regular expressions",
"homepage": "http://xregexp.com/",
"authors": [
15 changes: 10 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "xregexp",
"version": "3.1.1",
"version": "3.2.0",
"description": "Extended regular expressions",
"homepage": "http://xregexp.com/",
"author": "Steven Levithan <steves_list@hotmail.com>",
@@ -15,14 +15,19 @@
"regular expression",
"unicode"
],
"main": "./src/index.js",
"main": "xregexp-all.js",
"files": [
"src"
"src",
"xregexp-all.js",
"LICENSE"
],
"scripts": {
"build": "browserify src/index.js --standalone XRegExp > xregexp-all.js"
"build": "browserify src/index.js --standalone XRegExp > xregexp-all.js",
"pretest": "npm run build",
"test": "jasmine JASMINE_CONFIG_PATH=tests/jasmine.json"
},
"devDependencies": {
"browserify": "^12.0.1"
"browserify": "^12.0.1",
"jasmine": "^2.5.3"
}
}
81 changes: 44 additions & 37 deletions src/addons/build.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
/*!
* XRegExp.build 3.1.1
* XRegExp.build 3.2.0
* <xregexp.com>
* Steven Levithan (c) 2012-2016 MIT License
* Steven Levithan (c) 2012-2017 MIT License
* Inspired by Lea Verou's RegExp.create <lea.verou.me>
*/

module.exports = function(XRegExp) {
'use strict';

var REGEX_DATA = 'xregexp';
var subParts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g;
var parts = XRegExp.union([/\({{([\w$]+)}}\)|{{([\w$]+)}}/, subParts], 'g');
var subParts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*\]/g;
var parts = XRegExp.union([/\({{([\w$]+)}}\)|{{([\w$]+)}}/, subParts], 'g', {
conjunction: 'or'
});

/**
* Strips a leading `^` and trailing unescaped `$`, if both are present.
*
* @private
* @param {String} pattern Pattern to process.
* @returns {String} Pattern with edge anchors removed.
*/
function deanchor(pattern) {
// Allow any number of empty noncapturing groups before/after anchors, because regexes
// built/generated by XRegExp sometimes include them
var leadingAnchor = /^(?:\(\?:\))*\^/,
trailingAnchor = /\$(?:\(\?:\))*$/;
var leadingAnchor = /^(?:\(\?:\))*\^/;
var trailingAnchor = /\$(?:\(\?:\))*$/;

if (
leadingAnchor.test(pattern) &&
@@ -39,26 +42,31 @@ module.exports = function(XRegExp) {
/**
* Converts the provided value to an XRegExp. Native RegExp flags are not preserved.
*
* @private
* @param {String|RegExp} value Value to convert.
* @param {Boolean} [addFlagX] Whether to apply the `x` flag in cases when `value` is not
* already a regex generated by XRegExp
* @returns {RegExp} XRegExp object with XRegExp syntax applied.
*/
function asXRegExp(value) {
function asXRegExp(value, addFlagX) {
var flags = addFlagX ? 'x' : '';
return XRegExp.isRegExp(value) ?
(value[REGEX_DATA] && value[REGEX_DATA].captureNames ?
// Don't recompile, to preserve capture names
value :
// Recompile as XRegExp
XRegExp(value.source)
XRegExp(value.source, flags)
) :
// Compile string as XRegExp
XRegExp(value);
XRegExp(value, flags);
}

/**
* Builds regexes using named subpatterns, for readability and pattern reuse. Backreferences in
* the outer pattern and provided subpatterns are automatically renumbered to work correctly.
* Native flags used by provided subpatterns are ignored in favor of the `flags` argument.
*
* @memberOf XRegExp
* @param {String} pattern XRegExp pattern using `{{name}}` for embedded subpatterns. Allows
* `({{name}})` as shorthand for `(?<name>{{name}})`. Patterns cannot be embedded within
* character classes.
@@ -79,50 +87,49 @@ module.exports = function(XRegExp) {
* XRegExp.exec('10:59', time).minutes; // -> '59'
*/
XRegExp.build = function(pattern, subs, flags) {
var inlineFlags = /^\(\?([\w$]+)\)/.exec(pattern),
data = {},
numCaps = 0, // 'Caps' is short for captures
numPriorCaps,
numOuterCaps = 0,
outerCapsMap = [0],
outerCapNames,
sub,
p;

flags = flags || '';
// Used with `asXRegExp` calls for `pattern` and subpatterns in `subs`, to work around how
// some browsers convert `RegExp('\n')` to a regex that contains the literal characters `\`
// and `n`. See more details at <https://github.com/slevithan/xregexp/pull/163>.
var addFlagX = flags.indexOf('x') > -1;
var inlineFlags = /^\(\?([\w$]+)\)/.exec(pattern);
// Add flags within a leading mode modifier to the overall pattern's flags
if (inlineFlags) {
flags = flags || '';
inlineFlags[1].replace(/./g, function(flag) {
// Don't add duplicates
flags += (flags.indexOf(flag) > -1 ? '' : flag);
});
flags = XRegExp._clipDuplicates(flags + inlineFlags[1]);
}

for (p in subs) {
var data = {};
for (var p in subs) {
if (subs.hasOwnProperty(p)) {
// Passing to XRegExp enables extended syntax and ensures independent validity,
// lest an unescaped `(`, `)`, `[`, or trailing `\` breaks the `(?:)` wrapper. For
// subpatterns provided as native regexes, it dies on octals and adds the property
// used to hold extended regex instance data, for simplicity
sub = asXRegExp(subs[p]);
// used to hold extended regex instance data, for simplicity.
var sub = asXRegExp(subs[p], addFlagX);
data[p] = {
// Deanchoring allows embedding independently useful anchored regexes. If you
// really need to keep your anchors, double them (i.e., `^^...$$`)
// really need to keep your anchors, double them (i.e., `^^...$$`).
pattern: deanchor(sub.source),
names: sub[REGEX_DATA].captureNames || []
};
}
}

// Passing to XRegExp dies on octals and ensures the outer pattern is independently valid;
// helps keep this simple. Named captures will be put back
pattern = asXRegExp(pattern);
outerCapNames = pattern[REGEX_DATA].captureNames || [];
pattern = pattern.source.replace(parts, function($0, $1, $2, $3, $4) {
var subName = $1 || $2,
capName,
intro,
localCapIndex;
// helps keep this simple. Named captures will be put back.
var patternAsRegex = asXRegExp(pattern, addFlagX);

// 'Caps' is short for 'captures'
var numCaps = 0;
var numPriorCaps;
var numOuterCaps = 0;
var outerCapsMap = [0];
var outerCapNames = patternAsRegex[REGEX_DATA].captureNames || [];
var output = patternAsRegex.source.replace(parts, function($0, $1, $2, $3, $4) {
var subName = $1 || $2;
var capName;
var intro;
var localCapIndex;
// Named subpattern
if (subName) {
if (!data.hasOwnProperty(subName)) {
@@ -180,7 +187,7 @@ module.exports = function(XRegExp) {
return $0;
});

return XRegExp(pattern, flags);
return XRegExp(output, flags);
};

};
Loading