forked from mirror/glob
Readme, docs
This commit is contained in:
parent
b601cfa2a5
commit
de5292400f
17
glob.go
17
glob.go
|
@ -12,12 +12,26 @@ type Glob interface {
|
||||||
//
|
//
|
||||||
// pattern:
|
// pattern:
|
||||||
// { term }
|
// { term }
|
||||||
|
//
|
||||||
// term:
|
// term:
|
||||||
// `*` matches any sequence of non-separator characters
|
// `*` matches any sequence of non-separator characters
|
||||||
// `**` matches any sequence of characters
|
// `**` matches any sequence of characters
|
||||||
// `?` matches any single non-separator character
|
// `?` matches any single non-separator character
|
||||||
// c matches character c (c != `*`, `**`, `?`, `\`)
|
// `[` [ `!` ] { character-range } `]`
|
||||||
|
// character class (must be non-empty)
|
||||||
|
// `{` pattern-list `}`
|
||||||
|
// pattern alternatives
|
||||||
|
// c matches character c (c != `*`, `**`, `?`, `\`, `[`, `{`, `}`)
|
||||||
// `\` c matches character c
|
// `\` c matches character c
|
||||||
|
//
|
||||||
|
// character-range:
|
||||||
|
// c matches character c (c != `\\`, `-`, `]`)
|
||||||
|
// `\` c matches character c
|
||||||
|
// lo `-` hi matches character c for lo <= c <= hi
|
||||||
|
//
|
||||||
|
// pattern-list:
|
||||||
|
// pattern { `,` pattern }
|
||||||
|
// comma-separated (without spaces) patterns
|
||||||
func Compile(pattern string, separators ...string) (Glob, error) {
|
func Compile(pattern string, separators ...string) (Glob, error) {
|
||||||
ast, err := parse(newLexer(pattern))
|
ast, err := parse(newLexer(pattern))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,6 +46,7 @@ func Compile(pattern string, separators ...string) (Glob, error) {
|
||||||
return matcher, nil
|
return matcher, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustCompile is the same as Compile, except that if Compile returns error, this will panic
|
||||||
func MustCompile(pattern string, separators ...string) Glob {
|
func MustCompile(pattern string, separators ...string) Glob {
|
||||||
g, err := Compile(pattern, separators...)
|
g, err := Compile(pattern, separators...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
79
readme.md
79
readme.md
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[![GoDoc][godoc-image]][godoc-url] [![Build Status][travis-image]][travis-url]
|
[![GoDoc][godoc-image]][godoc-url] [![Build Status][travis-image]][travis-url]
|
||||||
|
|
||||||
> Simple globbing library.
|
> Go Globbing Library.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
@ -22,55 +22,92 @@ func main() {
|
||||||
var g glob.Glob
|
var g glob.Glob
|
||||||
|
|
||||||
// create simple glob
|
// create simple glob
|
||||||
g = glob.New("*.github.com")
|
g = glob.MustCompile("*.github.com")
|
||||||
g.Match("api.github.com") // true
|
g.Match("api.github.com") // true
|
||||||
|
|
||||||
// create new glob with set of delimiters as ["."]
|
// create new glob with set of delimiters as ["."]
|
||||||
g = glob.New("api.*.com", ".")
|
g = glob.MustCompile("api.*.com", ".")
|
||||||
g.Match("api.github.com") // true
|
g.Match("api.github.com") // true
|
||||||
g.Match("api.gi.hub.com") // false
|
g.Match("api.gi.hub.com") // false
|
||||||
|
|
||||||
// create new glob with set of delimiters as ["."]
|
// create new glob with set of delimiters as ["."]
|
||||||
// but now with super wildcard
|
// but now with super wildcard
|
||||||
g = glob.New("api.**.com", ".")
|
g = glob.MustCompile("api.**.com", ".")
|
||||||
g.Match("api.github.com") // true
|
g.Match("api.github.com") // true
|
||||||
g.Match("api.gi.hub.com") // true
|
g.Match("api.gi.hub.com") // true
|
||||||
|
|
||||||
// create glob with single symbol wildcard
|
// create glob with single symbol wildcard
|
||||||
g = glob.New("?at")
|
g = glob.MustCompile("?at")
|
||||||
g.Match("cat") // true
|
g.Match("cat") // true
|
||||||
g.Match("fat") // true
|
g.Match("fat") // true
|
||||||
g.Match("at") // false
|
g.Match("at") // false
|
||||||
|
|
||||||
// create glob with single symbol wildcard and delimiters ["f"]
|
// create glob with single symbol wildcard and delimiters ["f"]
|
||||||
g = glob.New("?at", "f")
|
g = glob.MustCompile("?at", "f")
|
||||||
g.Match("cat") // true
|
g.Match("cat") // true
|
||||||
g.Match("fat") // false
|
g.Match("fat") // false
|
||||||
g.Match("at") // false
|
g.Match("at") // false
|
||||||
|
|
||||||
|
// create glob with character-list matchers
|
||||||
|
g = glob.MustCompile("[abc]at")
|
||||||
|
g.Match("cat") // true
|
||||||
|
g.Match("bat") // true
|
||||||
|
g.Match("fat") // false
|
||||||
|
g.Match("at") // false
|
||||||
|
|
||||||
|
// create glob with character-list matchers
|
||||||
|
g = glob.MustCompile("[!abc]at")
|
||||||
|
g.Match("cat") // false
|
||||||
|
g.Match("bat") // false
|
||||||
|
g.Match("fat") // true
|
||||||
|
g.Match("at") // false
|
||||||
|
|
||||||
|
// create glob with character-range matchers
|
||||||
|
g = glob.MustCompile("[a-c]at")
|
||||||
|
g.Match("cat") // true
|
||||||
|
g.Match("bat") // true
|
||||||
|
g.Match("fat") // false
|
||||||
|
g.Match("at") // false
|
||||||
|
|
||||||
|
// create glob with character-range matchers
|
||||||
|
g = glob.MustCompile("[!a-c]at")
|
||||||
|
g.Match("cat") // false
|
||||||
|
g.Match("bat") // false
|
||||||
|
g.Match("fat") // true
|
||||||
|
g.Match("at") // false
|
||||||
|
|
||||||
|
|
||||||
|
// create glob with pattern-alternatives list
|
||||||
|
g = glob.MustCompile("{cat,bat,[fr]at}")
|
||||||
|
g.Match("cat") // true
|
||||||
|
g.Match("bat") // true
|
||||||
|
g.Match("fat") // true
|
||||||
|
g.Match("rat") // true
|
||||||
|
g.Match("at") // false
|
||||||
|
g.Match("zat") // false
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
In comparison with [go-glob](https://github.com/ryanuber/go-glob), it is ~2.5x faster (on my Mac),
|
This library is created for compile-once patterns. This means, that compilation could take time, but
|
||||||
because my impl compiles patterns for future usage. If you will not use compiled `glob.Glob` object,
|
strings matching is done faster, than in case when always parsing template.
|
||||||
and do `g := glob.New(pattern); g.Match(...)` every time, then your code will be about ~3x slower.
|
|
||||||
|
|
||||||
Run `go test bench=.` from source root to see the benchmarks:
|
If you will not use compiled `glob.Glob` object, and do `g := glob.MustCompile(pattern); g.Match(...)` every time, then your code will be much more slower.
|
||||||
|
|
||||||
Test | Operations | Speed
|
Run `go test -bench=.` from source root to see the benchmarks:
|
||||||
-----|------------|------
|
|
||||||
github.com/gobwas/glob | 20000000 | 150 ns/op
|
|
||||||
github.com/ryanuber/go-glob | 10000000 | 375 ns/op
|
|
||||||
|
|
||||||
Also, there are few simple optimizations, that help to test much faster patterns like `*abc`, `abc*` or `a*c`:
|
Pattern | Fixture | Operations | Speed (ns/op)
|
||||||
|
--------|---------|------------|--------------
|
||||||
Test | Operations | Speed
|
`[a-z][!a-x]*cat*[h][!b]*eyes*` | | 50000 | 26497
|
||||||
-----|------------|------
|
`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my cat has very bright eyes` | 2000000 | 615
|
||||||
prefix | 200000000 | 8.78 ns/op
|
`https://*.google.*` | `https://account.google.com` | 10000000 | 121
|
||||||
suffix | 200000000 | 9.46 ns/op
|
`{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}` | `http://yahoo.com` | 10000000 | 167
|
||||||
prefix-suffix | 100000000 | 16.3 ns/op
|
`{https://*gobwas.com,http://exclude.gobwas.com}` | `https://safe.gobwas.com` | 50000000 | 24.7
|
||||||
|
`abc*` | `abcdef` | 200000000 | 9.49
|
||||||
|
`*def` | `abcdef` | 200000000 | 9.60 ns/op
|
||||||
|
`ab*ef` | `abcdef` | 100000000 | 15.2
|
||||||
|
|
||||||
[godoc-image]: https://godoc.org/github.com/gobwas/glob?status.svg
|
[godoc-image]: https://godoc.org/github.com/gobwas/glob?status.svg
|
||||||
[godoc-url]: https://godoc.org/github.com/gobwas/glob
|
[godoc-url]: https://godoc.org/github.com/gobwas/glob
|
||||||
|
|
Loading…
Reference in New Issue