glob-to-regexp
Advanced tools
Comparing version 0.1.0 to 0.2.0
28
index.js
module.exports = function (glob, opts) { | ||
if (glob == null) { | ||
return null; | ||
if (typeof glob !== 'string') { | ||
throw new TypeError('Expected a string'); | ||
} | ||
@@ -16,2 +16,13 @@ | ||
// When globstar is _false_ (default), '/foo/*' is translated a regexp like | ||
// '^\/foo\/.*$' which will match any string beginning with '/foo/' | ||
// When globstar is _true_, '/foo/*' is translated to regexp like | ||
// '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT | ||
// which does not have a '/' to the right of it. | ||
// E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but | ||
// these will not '/foo/bar/baz', '/foo/bar/baz.txt' | ||
// Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when | ||
// globstar is _false_ | ||
var globstar = opts ? !!opts.globstar : false; | ||
// If we are doing extended matching, this boolean is true when we are inside | ||
@@ -77,3 +88,14 @@ // a group (eg {*.html,*.js}), and false otherwise. | ||
case "*": | ||
reStr += ".*"; | ||
if (!globstar) { | ||
reStr += ".*"; | ||
} else { | ||
if (str[i + 1] === "*") { | ||
reStr += ".*"; | ||
i++; // move over second '*' | ||
} else { | ||
reStr += "[^/]*"; | ||
} | ||
} | ||
// move over repeated *'s | ||
while(str[i + 1] === "*") i++; | ||
break; | ||
@@ -80,0 +102,0 @@ |
{ | ||
"name": "glob-to-regexp", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Convert globs to regular expressions", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -12,2 +12,12 @@ # Glob To Regular Expression | ||
To obey [globstars `**`](https://github.com/isaacs/node-glob#glob-primer) rules set option `{globstar: true}`. | ||
NOTE: This changes the behavior of `*` when `globstar` is `true` as shown below: | ||
When `{globstar: true}`: `/foo/**` will match any string that starts with `/foo/` | ||
like `/foo/index.htm`, `/foo/bar/baz.txt`, etc. Also, `/foo/**/*.txt` will match | ||
any string that starts with `/foo/` and ends with `.txt` like `/foo/bar.txt`, | ||
`/foo/bar/baz.txt`, etc. | ||
Whereas `/foo/*` (single `*`, not a globstar) will match strings that start with | ||
`/foo/` like `/foo/index.htm`, `/foo/baz.txt` but will not match strings that | ||
contain a `/` to the right like `/foo/bar/baz.txt`, `/foo/bar/baz/qux.dat`, etc. | ||
Set flags on the resulting `RegExp` object by adding the `flags` property to the option object, eg `{ flags: "i" }` for ignoring case. | ||
@@ -20,21 +30,23 @@ | ||
## Usage | ||
```js | ||
var globToRegExp = require('glob-to-regexp'); | ||
var re = globToRegExp("p*uck"); | ||
re.test("pot luck"); // true | ||
re.test("pluck"); // true | ||
re.test("puck"); // true | ||
var globToRegExp = require('glob-to-regexp'); | ||
var re = globToRegExp("f*uck"); | ||
re.test("firetruck"); // true | ||
re.test("fuck"); // true | ||
re = globToRegExp("*.min.js"); | ||
re.test("http://example.com/jquery.min.js"); // true | ||
re.test("http://example.com/jquery.min.js.map"); // false | ||
re = globToRegExp("*.min.js"); | ||
re.test("http://example.com/jquery.min.js"); // true | ||
re.test("http://example.com/jquery.min.js.map"); // false | ||
re = globToRegExp("*/www/*.js"); | ||
re.test("http://example.com/www/app.js"); // true | ||
re.test("http://example.com/www/lib/factory-proxy-model-observer.js"); // true | ||
re = globToRegExp("*/www/*.js"); | ||
re.test("http://example.com/www/app.js"); // true | ||
re.test("http://example.com/www/lib/factory-proxy-model-observer.js"); // true | ||
// Extended globs | ||
re = globToRegExp("*/www/{*.js,*.html}", { extended: true }); | ||
re.test("http://example.com/www/app.js"); // true | ||
re.test("http://example.com/www/index.html"); // true | ||
``` | ||
// Extended globs | ||
re = globToRegExp("*/www/{*.js,*.html}", { extended: true }); | ||
re.test("http://example.com/www/app.js"); // true | ||
re.test("http://example.com/www/index.html"); // true | ||
## License | ||
@@ -41,0 +53,0 @@ |
288
test.js
@@ -5,2 +5,3 @@ var globToRegexp = require("./index.js"); | ||
function assertMatch(glob, str, opts) { | ||
//console.log(glob, globToRegexp(glob, opts)); | ||
assert.ok(globToRegexp(glob, opts).test(str)); | ||
@@ -10,140 +11,205 @@ } | ||
function assertNotMatch(glob, str, opts) { | ||
//console.log(glob, globToRegexp(glob, opts)); | ||
assert.equal(false, globToRegexp(glob, opts).test(str)); | ||
} | ||
// Match everything | ||
assertMatch("*", "foo"); | ||
assertMatch("*", "foo", { flags: 'g' }); | ||
function test(globstar) { | ||
// Match everything | ||
assertMatch("*", "foo"); | ||
assertMatch("*", "foo", { flags: 'g' }); | ||
// Match the end | ||
assertMatch("f*", "foo"); | ||
assertMatch("f*", "foo", { flags: 'g' }); | ||
// Match the end | ||
assertMatch("f*", "foo"); | ||
assertMatch("f*", "foo", { flags: 'g' }); | ||
// Match the start | ||
assertMatch("*o", "foo"); | ||
assertMatch("*o", "foo", { flags: 'g' }); | ||
// Match the start | ||
assertMatch("*o", "foo"); | ||
assertMatch("*o", "foo", { flags: 'g' }); | ||
// Match the middle | ||
assertMatch("f*uck", "firetruck"); | ||
assertMatch("f*uck", "firetruck", { flags: 'g' }); | ||
// Match the middle | ||
assertMatch("f*uck", "firetruck"); | ||
assertMatch("f*uck", "firetruck", { flags: 'g' }); | ||
// Don't match without Regexp 'g' | ||
assertNotMatch("uc", "firetruck"); | ||
// Match anywhere with RegExp 'g' | ||
assertMatch("uc", "firetruck", { flags: 'g' }); | ||
// Don't match without Regexp 'g' | ||
assertNotMatch("uc", "firetruck"); | ||
// Match anywhere with RegExp 'g' | ||
assertMatch("uc", "firetruck", { flags: 'g' }); | ||
// Match zero characters | ||
assertMatch("f*uck", "fuck"); | ||
assertMatch("f*uck", "fuck", { flags: 'g' }); | ||
// Match zero characters | ||
assertMatch("f*uck", "fuck"); | ||
assertMatch("f*uck", "fuck", { flags: 'g' }); | ||
// More complex matches | ||
assertMatch("*.min.js", "http://example.com/jquery.min.js"); | ||
assertMatch("*.min.*", "http://example.com/jquery.min.js"); | ||
assertMatch("*/js/*.js", "http://example.com/js/jquery.min.js"); | ||
// More complex matches | ||
assertMatch("*.min.js", "http://example.com/jquery.min.js", {globstar: false}); | ||
assertMatch("*.min.*", "http://example.com/jquery.min.js", {globstar: false}); | ||
assertMatch("*/js/*.js", "http://example.com/js/jquery.min.js", {globstar: false}); | ||
// More complex matches with RegExp 'g' flag (complex regression) | ||
assertMatch("*.min.*", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertMatch("*.min.js", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertMatch("*/js/*.js", "http://example.com/js/jquery.min.js", { flags: 'g' }); | ||
// More complex matches with RegExp 'g' flag (complex regression) | ||
assertMatch("*.min.*", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertMatch("*.min.js", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertMatch("*/js/*.js", "http://example.com/js/jquery.min.js", { flags: 'g' }); | ||
var testStr = "\\/$^+?.()=!|{},[].*" | ||
assertMatch(testStr, testStr); | ||
assertMatch(testStr, testStr, { flags: 'g' }); | ||
var testStr = "\\/$^+?.()=!|{},[].*" | ||
assertMatch(testStr, testStr); | ||
assertMatch(testStr, testStr, { flags: 'g' }); | ||
// Equivalent matches without/with using RegExp 'g' | ||
assertNotMatch(".min.", "http://example.com/jquery.min.js"); | ||
assertMatch("*.min.*", "http://example.com/jquery.min.js"); | ||
assertMatch(".min.", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
// Equivalent matches without/with using RegExp 'g' | ||
assertNotMatch(".min.", "http://example.com/jquery.min.js"); | ||
assertMatch("*.min.*", "http://example.com/jquery.min.js"); | ||
assertMatch(".min.", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertNotMatch("http:", "http://example.com/jquery.min.js"); | ||
assertMatch("http:*", "http://example.com/jquery.min.js"); | ||
assertMatch("http:", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertNotMatch("http:", "http://example.com/jquery.min.js"); | ||
assertMatch("http:*", "http://example.com/jquery.min.js"); | ||
assertMatch("http:", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertNotMatch("min.js", "http://example.com/jquery.min.js"); | ||
assertMatch("*.min.js", "http://example.com/jquery.min.js"); | ||
assertMatch("min.js", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertNotMatch("min.js", "http://example.com/jquery.min.js"); | ||
assertMatch("*.min.js", "http://example.com/jquery.min.js"); | ||
assertMatch("min.js", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
// Match anywhere (globally) using RegExp 'g' | ||
assertMatch("min", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertMatch("/js/", "http://example.com/js/jquery.min.js", { flags: 'g' }); | ||
// Match anywhere (globally) using RegExp 'g' | ||
assertMatch("min", "http://example.com/jquery.min.js", { flags: 'g' }); | ||
assertMatch("/js/", "http://example.com/js/jquery.min.js", { flags: 'g' }); | ||
assertNotMatch("/js*jq*.js", "http://example.com/js/jquery.min.js"); | ||
assertMatch("/js*jq*.js", "http://example.com/js/jquery.min.js", { flags: 'g' }); | ||
assertNotMatch("/js*jq*.js", "http://example.com/js/jquery.min.js"); | ||
assertMatch("/js*jq*.js", "http://example.com/js/jquery.min.js", { flags: 'g' }); | ||
// Extended mode | ||
// Extended mode | ||
// ?: Match one character, no more and no less | ||
assertMatch("f?o", "foo", { extended: true }); | ||
assertNotMatch("f?o", "fooo", { extended: true }); | ||
assertNotMatch("f?oo", "foo", { extended: true }); | ||
// ?: Match one character, no more and no less | ||
assertMatch("f?o", "foo", { extended: true }); | ||
assertNotMatch("f?o", "fooo", { extended: true }); | ||
assertNotMatch("f?oo", "foo", { extended: true }); | ||
// ?: Match one character with RegExp 'g' | ||
assertMatch("f?o", "foo", { extended: true, flags: 'g' }); | ||
assertMatch("f?o", "fooo", { extended: true, flags: 'g' }); | ||
assertMatch("f?o?", "fooo", { extended: true, flags: 'g' }); | ||
assertNotMatch("?fo", "fooo", { extended: true, flags: 'g' }); | ||
assertNotMatch("f?oo", "foo", { extended: true, flags: 'g' }); | ||
assertNotMatch("foo?", "foo", { extended: true, flags: 'g' }); | ||
// ?: Match one character with RegExp 'g' | ||
assertMatch("f?o", "foo", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("f?o", "fooo", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("f?o?", "fooo", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("?fo", "fooo", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("f?oo", "foo", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("foo?", "foo", { extended: true, globstar: globstar, flags: 'g' }); | ||
// []: Match a character range | ||
assertMatch("fo[oz]", "foo", { extended: true }); | ||
assertMatch("fo[oz]", "foz", { extended: true }); | ||
assertNotMatch("fo[oz]", "fog", { extended: true }); | ||
// []: Match a character range | ||
assertMatch("fo[oz]", "foo", { extended: true }); | ||
assertMatch("fo[oz]", "foz", { extended: true }); | ||
assertNotMatch("fo[oz]", "fog", { extended: true }); | ||
// []: Match a character range and RegExp 'g' (regresion) | ||
assertMatch("fo[oz]", "foo", { extended: true, flags: 'g' }); | ||
assertMatch("fo[oz]", "foz", { extended: true, flags: 'g' }); | ||
assertNotMatch("fo[oz]", "fog", { extended: true, flags: 'g' }); | ||
// []: Match a character range and RegExp 'g' (regresion) | ||
assertMatch("fo[oz]", "foo", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("fo[oz]", "foz", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("fo[oz]", "fog", { extended: true, globstar: globstar, flags: 'g' }); | ||
// {}: Match a choice of different substrings | ||
assertMatch("foo{bar,baaz}", "foobaaz", { extended: true }); | ||
assertMatch("foo{bar,baaz}", "foobar", { extended: true }); | ||
assertNotMatch("foo{bar,baaz}", "foobuzz", { extended: true }); | ||
assertMatch("foo{bar,b*z}", "foobuzz", { extended: true }); | ||
// {}: Match a choice of different substrings | ||
assertMatch("foo{bar,baaz}", "foobaaz", { extended: true }); | ||
assertMatch("foo{bar,baaz}", "foobar", { extended: true }); | ||
assertNotMatch("foo{bar,baaz}", "foobuzz", { extended: true }); | ||
assertMatch("foo{bar,b*z}", "foobuzz", { extended: true }); | ||
// {}: Match a choice of different substrings and RegExp 'g' (regression) | ||
assertMatch("foo{bar,baaz}", "foobaaz", { extended: true, flags: 'g' }); | ||
assertMatch("foo{bar,baaz}", "foobar", { extended: true, flags: 'g' }); | ||
assertNotMatch("foo{bar,baaz}", "foobuzz", { extended: true, flags: 'g' }); | ||
assertMatch("foo{bar,b*z}", "foobuzz", { extended: true, flags: 'g' }); | ||
// {}: Match a choice of different substrings and RegExp 'g' (regression) | ||
assertMatch("foo{bar,baaz}", "foobaaz", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("foo{bar,baaz}", "foobar", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("foo{bar,baaz}", "foobuzz", { extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("foo{bar,b*z}", "foobuzz", { extended: true, globstar: globstar, flags: 'g' }); | ||
// More complex extended matches | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://foo.baaz.com/jquery.min.js", | ||
{ extended: true }); | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.html", | ||
{ extended: true }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.htm", | ||
{ extended: true }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.bar.com/index.html", | ||
{ extended: true }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://flozz.buzz.com/index.html", | ||
{ extended: true }); | ||
// More complex extended matches | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://foo.baaz.com/jquery.min.js", | ||
{ extended: true }); | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.html", | ||
{ extended: true }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.htm", | ||
{ extended: true }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.bar.com/index.html", | ||
{ extended: true }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://flozz.buzz.com/index.html", | ||
{ extended: true }); | ||
// More complex extended matches and RegExp 'g' (regresion) | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://foo.baaz.com/jquery.min.js", | ||
{ extended: true, flags: 'g' }); | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.html", | ||
{ extended: true, flags: 'g' }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.htm", | ||
{ extended: true, flags: 'g' }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.bar.com/index.html", | ||
{ extended: true, flags: 'g' }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://flozz.buzz.com/index.html", | ||
{ extended: true, flags: 'g' }); | ||
// More complex extended matches and RegExp 'g' (regresion) | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://foo.baaz.com/jquery.min.js", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.html", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.buzz.com/index.htm", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://moz.bar.com/index.html", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}", | ||
"http://flozz.buzz.com/index.html", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
// Remaining special chars should still match themselves | ||
var testExtStr = "\\/$^+.()=!|,.*" | ||
assertMatch(testExtStr, testExtStr, { extended: true }); | ||
assertMatch(testExtStr, testExtStr, { extended: true, flags: 'g' }); | ||
// globstar | ||
assertMatch("http://foo.com/**/{*.js,*.html}", | ||
"http://foo.com/bar/jquery.min.js", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("http://foo.com/**/{*.js,*.html}", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
assertMatch("http://foo.com/**", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ extended: true, globstar: globstar, flags: 'g' }); | ||
// Remaining special chars should still match themselves | ||
var testExtStr = "\\/$^+.()=!|,.*" | ||
assertMatch(testExtStr, testExtStr, { extended: true }); | ||
assertMatch(testExtStr, testExtStr, { extended: true, globstar: globstar, flags: 'g' }); | ||
} | ||
// regression | ||
// globstar false | ||
test(false) | ||
// globstar true | ||
test(true); | ||
// globstar specific tests | ||
assertMatch("/foo/*", "/foo/bar.txt", {globstar: true }); | ||
assertMatch("/foo/**", "/foo/baz.txt", {globstar: true }); | ||
assertMatch("/foo/**", "/foo/bar/baz.txt", {globstar: true }); | ||
assertMatch("/foo/*/*.txt", "/foo/bar/baz.txt", {globstar: true }); | ||
assertMatch("/foo/**/*.txt", "/foo/bar/baz.txt", {globstar: true }); | ||
assertMatch("/foo/**/*.txt", "/foo/bar/baz/qux.txt", {globstar: true }); | ||
assertMatch("**/*.txt", "/foo/bar/baz/qux.txt", {globstar: true }); | ||
assertNotMatch("/foo/*", "/foo/bar/baz.txt", {globstar: true }); | ||
assertNotMatch("/foo/*.txt", "/foo/bar/baz.txt", {globstar: true }); | ||
assertNotMatch("/foo/*/*.txt", "/foo/bar/baz/qux.txt", {globstar: true }); | ||
assertNotMatch("**/.txt", "/foo/bar/baz/qux.txt", {globstar: true }); | ||
assertNotMatch("*/*.txt", "/foo/bar/baz/qux.txt", {globstar: true }); | ||
assertNotMatch("http://foo.com/*", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ extended: true, globstar: true }); | ||
assertNotMatch("http://foo.com/*", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: true }); | ||
assertMatch("http://foo.com/*", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: false }); | ||
assertMatch("http://foo.com/**", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: true }); | ||
assertMatch("http://foo.com/*/*/jquery.min.js", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: true }); | ||
assertMatch("http://foo.com/**/jquery.min.js", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: true }); | ||
assertMatch("http://foo.com/*/*/jquery.min.js", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: false }); | ||
assertMatch("http://foo.com/*/jquery.min.js", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: false }); | ||
assertNotMatch("http://foo.com/*/jquery.min.js", | ||
"http://foo.com/bar/baz/jquery.min.js", | ||
{ globstar: true }); | ||
console.log("Ok!"); |
15913
277
76