Comparing version 2.0.0 to 3.0.0
{ | ||
"name": "xregexp", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "Extended regular expressions", | ||
"homepage": "http://xregexp.com/", | ||
"author": "Steven Levithan <steves_list@hotmail.com>", | ||
"license": "MIT", | ||
"repository" : { | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/slevithan/XRegExp.git" | ||
"url": "https://github.com/slevithan/xregexp.git" | ||
}, | ||
"description": "Extended JavaScript regular expressions", | ||
"keywords": ["regex", "regexp"], | ||
"main": "./xregexp-all.js", | ||
"keywords": [ | ||
"regex", | ||
"regexp" | ||
], | ||
"main": "xregexp-all.js", | ||
"files": [ | ||
"LICENSE", | ||
"xregexp-all.js" | ||
], | ||
"scripts": { | ||
"test": "node tests/node-qunit.js" | ||
}, | ||
"devDependencies": { | ||
"qunit": ">= 0.2.x" | ||
"build": "./tools/concatenate-source.sh" | ||
} | ||
} |
236
README.md
@@ -1,25 +0,23 @@ | ||
[XRegExp](http://xregexp.com/) | ||
============================== | ||
[XRegExp](http://xregexp.com/) 3.0.0 | ||
==================================== | ||
XRegExp provides augmented, extensible, cross-browser JavaScript regular expressions. You get new syntax and flags beyond what browsers support natively, along with a collection of utils to make your client-side grepping and parsing easier. XRegExp also frees you from worrying about pesky inconsistencies in cross-browser regex handling and the dubious `lastIndex` property. | ||
XRegExp provides augmented and extensible JavaScript regular expressions. You get new syntax, flags, and methods beyond what browsers support natively. XRegExp is also a regex utility belt with tools to make your client-side grepping simpler and more powerful, while freeing you from worrying about pesky cross-browser inconsistencies and things like manually manipulating `lastIndex` or slicing strings when tokenizing. | ||
XRegExp supports all native ES5 regular expression syntax. It's about 3.5 KB when minified and gzipped. It works with Internet Explorer 5.5+, Firefox 1.5+, Chrome, Safari 3+, and Opera 9.5+. | ||
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. The base library is about 4.25 KB, minified and gzipped. | ||
## Performance | ||
XRegExp regular expressions compile to native RegExp objects, thus there is no performance difference when using XRegExp objects with native methods. There is a small performance cost when *compiling* XRegExps. If you want, however, you can use `XRegExp.cache` to avoid ever incurring the compilation cost for a given pattern more than once. Doing so can even lead to XRegExp being faster than native regexes in synthetic tests that repeatedly compile the same regex. | ||
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. | ||
## Usage examples | ||
~~~ js | ||
```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 \n\ | ||
(?<month> [0-9]{2} ) -? # month \n\ | ||
(?<day> [0-9]{2} ) # day ', 'x'); | ||
// XRegExp.exec gives you named backreferences on the match result | ||
var match = XRegExp.exec('2012-02-22', date); | ||
match.day; // -> '22' | ||
var match = XRegExp.exec('2015-02-22', date); | ||
match.year; // -> '2015' | ||
@@ -34,26 +32,28 @@ // It also includes optional pos and sticky arguments | ||
// XRegExp.replace allows named backreferences in replacements | ||
XRegExp.replace('2012-02-22', date, '${month}/${day}/${year}'); // -> '02/22/2012' | ||
XRegExp.replace('2012-02-22', date, function (match) { | ||
XRegExp.replace('2015-02-22', date, '${month}/${day}/${year}'); // -> '02/22/2015' | ||
XRegExp.replace('2015-02-22', date, function(match) { | ||
return match.month + '/' + match.day + '/' + match.year; | ||
}); // -> '02/22/2012' | ||
}); // -> '02/22/2015' | ||
// In fact, all XRegExps are RegExps and work perfectly with native methods | ||
date.test('2012-02-22'); // -> true | ||
// In fact, XRegExps compile to RegExps and work perfectly with native methods | ||
date.test('2015-02-22'); // -> true | ||
// The *only* caveat is that named captures must be referred to using numbered backreferences | ||
'2012-02-22'.replace(date, '$2/$3/$1'); // -> '02/22/2012' | ||
// The *only* caveat is that named captures must be referenced using numbered backreferences | ||
'2015-02-22'.replace(date, '$2/$3/$1'); // -> '02/22/2015' | ||
// If you want, you can extend native methods so you don't have to worry about this | ||
// If you want, you can extend native methods so you don't have to worry about this. | ||
// Doing so also fixes numerous browser bugs in the native methods | ||
XRegExp.install('natives'); | ||
'2012-02-22'.replace(date, '${month}/${day}/${year}'); // -> '02/22/2012' | ||
'2012-02-22'.replace(date, function (match) { | ||
'2015-02-22'.replace(date, '${month}/${day}/${year}'); // -> '02/22/2015' | ||
'2015-02-22'.replace(date, function(match) { | ||
return match.month + '/' + match.day + '/' + match.year; | ||
}); // -> '02/22/2012' | ||
date.exec('2012-02-22').day; // -> '22' | ||
}); // -> '02/22/2015' | ||
date.exec('2015-02-22').year; // -> '2015' | ||
// Extract every other digit from a string using XRegExp.forEach | ||
XRegExp.forEach('1a2345', /\d/, function (match, i) { | ||
if (i % 2) this.push(+match[0]); | ||
}, []); // -> [2, 4] | ||
var evens = []; | ||
XRegExp.forEach('1a2345', /\d/, function(match, i) { | ||
if (i % 2) evens.push(+match[0]); | ||
}); | ||
// evens -> [2, 4] | ||
@@ -67,4 +67,4 @@ // Get numbers within <b> tags using XRegExp.matchChain | ||
// You can also pass forward and return specific backreferences | ||
var html = '<a href="http://xregexp.com/">XRegExp</a>\ | ||
<a href="http://www.google.com/">Google</a>'; | ||
var html = '<a href="http://xregexp.com/">XRegExp</a>' + | ||
'<a href="http://www.google.com/">Google</a>'; | ||
XRegExp.matchChain(html, [ | ||
@@ -75,43 +75,53 @@ {regex: /<a href="([^"]+)">/i, backref: 1}, | ||
// XRegExp.union safely merges strings and regexes into a single pattern | ||
XRegExp.union(['a+b*c', /(dogs)\1/, /(cats)\1/], 'i'); | ||
// -> /a\+b\*c|(dogs)\1|(cats)\2/i | ||
~~~ | ||
// Merge strings and regexes into a single pattern, safely rewriting backreferences | ||
XRegExp.union(['a+b*c', /(dog)\1/, /(cat)\1/], 'i'); | ||
// -> /a\+b\*c|(dog)\1|(cat)\2/i | ||
``` | ||
These examples should give you the flavor of what's possible, but XRegExp has more syntax, flags, utils, 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 more details. | ||
These examples should give you 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 more details. | ||
## Addons | ||
In browsers, you can either load addons individually, or bundle all addons together with XRegExp by loading `xregexp-all.js`. XRegExp's [npm](http://npmjs.org/) package uses `xregexp-all.js`, which means that the addons are always available when XRegExp is installed on the server using npm. | ||
You can either load addons individually, or bundle all addons together with XRegExp by loading `xregexp-all.js`. XRegExp's [npm](http://npmjs.org/) package uses `xregexp-all.js`, so addons are always available when XRegExp is installed using npm. | ||
### Unicode | ||
### XRegExp Unicode Base | ||
In browsers, first include the Unicode Base script and then one or more of the addons for Unicode blocks, categories, properties, or scripts. | ||
In browsers, first include the Unicode Base script: | ||
```html | ||
<script src="src/xregexp.js"></script> | ||
<script src="src/addons/unicode-base.js"></script> | ||
<script src="src/addons/unicode-categories.js"></script> | ||
<script src="src/addons/unicode-scripts.js"></script> | ||
``` | ||
~~~ html | ||
<script src="xregexp.js"></script> | ||
<script src="addons/unicode/unicode-base.js"></script> | ||
~~~ | ||
Then you can do this: | ||
~~~ js | ||
var unicodeWord = XRegExp('^\\p{L}+$'); | ||
```js | ||
// Test the Unicode category L (Letter) | ||
var unicodeWord = XRegExp('^\\pL+$'); | ||
unicodeWord.test('Русский'); // -> true | ||
unicodeWord.test('日本語'); // -> true | ||
unicodeWord.test('العربية'); // -> true | ||
~~~ | ||
The base script adds `\p{Letter}` and its alias `\p{L}`, but other Unicode categories, scripts, blocks, and properties require addon packages. Try these next examples after additionally including `unicode-scripts.js`: | ||
~~~ js | ||
// Test some Unicode scripts | ||
XRegExp('^\\p{Hiragana}+$').test('ひらがな'); // -> true | ||
XRegExp('^[\\p{Latin}\\p{Common}]+$').test('Über Café.'); // -> true | ||
~~~ | ||
``` | ||
XRegExp uses the Unicode 6.1 Basic Multilingual Plane. | ||
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 apply astral mode 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. The test string uses a surrogate pair to represent U+1F4A9 | ||
XRegExp('^\\pS$', 'A').test('\uD83D\uDCA9'); // -> true | ||
// Implicit flag A | ||
XRegExp.install('astral'); | ||
XRegExp('^\\pS$').test('\uD83D\uDCA9'); // -> 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.build | ||
@@ -121,10 +131,10 @@ | ||
~~~ html | ||
<script src="xregexp.js"></script> | ||
<script src="addons/build.js"></script> | ||
~~~ | ||
```html | ||
<script src="src/xregexp.js"></script> | ||
<script src="src/addons/build.js"></script> | ||
``` | ||
You can then build regular expressions using named subpatterns, for readability and pattern reuse: | ||
~~~ js | ||
```js | ||
var time = XRegExp.build('(?x)^ {{hours}} ({{minutes}}) $', { | ||
@@ -134,3 +144,3 @@ hours: XRegExp.build('{{h12}} : | {{h24}}', { | ||
h24: /2[0-3]|[01][0-9]/ | ||
}, 'x'), | ||
}), | ||
minutes: /^[0-5][0-9]$/ | ||
@@ -141,9 +151,8 @@ }); | ||
XRegExp.exec('10:59', time).minutes; // -> '59' | ||
~~~ | ||
``` | ||
Named subpatterns can be provided as strings or regex objects. A leading `^` and trailing unescaped `$` are stripped from subpatterns if both are present, which allows embedding independently useful anchored patterns. `{{…}}` tokens can be quantified as a single unit. Backreferences in the outer pattern and provided subpatterns are automatically renumbered to work correctly within the larger combined pattern. The syntax `({{name}})` works as shorthand for named capture via `(?<name>{{name}})`. Named subpatterns cannot be embedded within character classes. | ||
Named subpatterns can be provided as strings or regex objects. A leading `^` and trailing unescaped `$` are stripped from subpatterns if both are present, which allows embedding independently-useful anchored patterns. `{{…}}` tokens can be quantified as a single unit. Any backreferences in the outer pattern or provided subpatterns are automatically renumbered to work correctly within the larger combined pattern. The syntax `({{name}})` works as shorthand for named capture via `(?<name>{{name}})`. Named subpatterns cannot be embedded within character classes. | ||
See also: *[Creating Grammatical Regexes Using XRegExp.build](http://blog.stevenlevithan.com/archives/grammatical-patterns-xregexp-build)*. | ||
### XRegExp.matchRecursive | ||
@@ -153,10 +162,10 @@ | ||
~~~ html | ||
<script src="xregexp.js"></script> | ||
<script src="addons/matchrecursive.js"></script> | ||
~~~ | ||
```html | ||
<script src="src/xregexp.js"></script> | ||
<script src="src/addons/matchrecursive.js"></script> | ||
``` | ||
You can then match recursive constructs using XRegExp pattern strings as left and right delimiters: | ||
~~~ js | ||
```js | ||
var str = '(t((e))s)t()(ing)'; | ||
@@ -196,38 +205,6 @@ XRegExp.matchRecursive(str, '\\(', '\\)', 'g'); | ||
// -> ['1', '<<2>>', '3'] | ||
~~~ | ||
``` | ||
`XRegExp.matchRecursive` throws an error if it sees an unbalanced delimiter in the target string. | ||
`XRegExp.matchRecursive` throws an error if it scans past an unbalanced delimiter in the target string. | ||
### XRegExp Prototype Methods | ||
In browsers, first include the script: | ||
~~~ html | ||
<script src="xregexp.js"></script> | ||
<script src="addons/prototypes.js"></script> | ||
~~~ | ||
New XRegExp regexes then gain a collection of useful methods: `apply`, `call`, `forEach`, `globalize`, `xexec`, and `xtest`. | ||
~~~ js | ||
// To demonstrate the call method, let's first create the function we'll be using... | ||
function filter(array, fn) { | ||
var res = []; | ||
array.forEach(function (el) {if (fn.call(null, el)) res.push(el);}); | ||
return res; | ||
} | ||
// Now we can filter arrays using functions and regexes | ||
filter(['a', 'ba', 'ab', 'b'], XRegExp('^a')); // -> ['a', 'ab'] | ||
~~~ | ||
Native `RegExp` objects copied by `XRegExp` are augmented with any `XRegExp.prototype` methods. The following lines therefore work equivalently: | ||
~~~ js | ||
XRegExp('[a-z]', 'ig').xexec('abc'); | ||
XRegExp(/[a-z]/ig).xexec('abc'); | ||
XRegExp.globalize(/[a-z]/i).xexec('abc'); | ||
~~~ | ||
## Installation and usage | ||
@@ -237,57 +214,50 @@ | ||
~~~ html | ||
<script src="xregexp-min.js"></script> | ||
~~~ | ||
```html | ||
<script src="src/xregexp.js"></script> | ||
``` | ||
Or, to bundle XRegExp with all of its addons: | ||
~~~ html | ||
<script src="xregexp-all-min.js"></script> | ||
~~~ | ||
```html | ||
<script src="xregexp-all.js"></script> | ||
``` | ||
Using [npm](http://npmjs.org/): | ||
~~~ bash | ||
```bash | ||
npm install xregexp | ||
~~~ | ||
``` | ||
In [Node.js](http://nodejs.org/) and [CommonJS module](http://wiki.commonjs.org/wiki/Modules) loaders: | ||
In [Node.js](http://nodejs.org/): | ||
~~~ js | ||
var XRegExp = require('xregexp').XRegExp; | ||
~~~ | ||
```js | ||
var XRegExp = require('xregexp'); | ||
``` | ||
The [CommonJS](http://wiki.commonjs.org/wiki/Modules)-style `require('xregexp').XRegExp` also works. | ||
In an AMD loader like [RequireJS](http://requirejs.org/): | ||
### Running tests on the server with npm | ||
```js | ||
require({paths: {xregexp: 'xregexp-all'}}, ['xregexp'], function(XRegExp) { | ||
console.log(XRegExp.version); | ||
}); | ||
``` | ||
~~~ bash | ||
npm install -g qunit # needed to run the tests | ||
npm test # in the xregexp root | ||
~~~ | ||
If XRegExp was not installed using npm, just open `tests/index.html` in your browser. | ||
## &c | ||
**Lookbehind:** A [collection of short functions](https://gist.github.com/2387872) is available that makes it easy to simulate infinite-length leading lookbehind. | ||
## Changelog | ||
* Releases: [Version history](http://xregexp.com/history/). | ||
* Upcoming: [Milestones](https://github.com/slevithan/XRegExp/issues/milestones), [Roadmap](https://github.com/slevithan/XRegExp/wiki/Roadmap). | ||
* Upcoming: [Issue tracker](https://github.com/slevithan/xregexp/issues). | ||
## About | ||
XRegExp and addons copyright 2007-2012 by [Steven Levithan](http://stevenlevithan.com/). | ||
XRegExp copyright 2007-2015 by [Steven Levithan](http://stevenlevithan.com/). | ||
Tools: Unicode range generators by [Mathias Bynens](http://mathiasbynens.be/). Source file concatenator by [Bjarke Walling](http://twitter.com/walling). | ||
Tools: Unicode range generators by [Mathias Bynens](http://mathiasbynens.be/), and adapted from his [unicode-data](https://github.com/mathiasbynens/unicode-data) project. Source file concatenator by [Bjarke Walling](http://twitter.com/walling). | ||
Prior art: `XRegExp.build` inspired by [Lea Verou](http://lea.verou.me/)'s [RegExp.create](http://lea.verou.me/2011/03/create-complex-regexps-more-easily/). `XRegExp.union` inspired by [Ruby](http://www.ruby-lang.org/). XRegExp's syntax extensions come from Perl, .NET, etc. | ||
Tests: Uses [Jasmine](http://pivotal.github.com/jasmine/) for unit tests, and [Benchmark.js](http://benchmarkjs.com) for performance tests. | ||
All code released under the [MIT License](http://mit-license.org/). | ||
Prior art: `XRegExp.build` inspired by [Lea Verou](http://lea.verou.me/)'s [RegExp.create](http://lea.verou.me/2011/03/create-complex-regexps-more-easily/). `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. | ||
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. | ||
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
236379
0
4518
0
4
255