forked from mirror/glob
Update
This commit is contained in:
parent
d4d579d13e
commit
678ba81174
88
glob.go
88
glob.go
|
@ -13,40 +13,28 @@ const (
|
|||
|
||||
var Chars = []string{Any, SuperAny, SingleAny}
|
||||
|
||||
type Matcher interface {
|
||||
type Glob interface {
|
||||
Match(string) bool
|
||||
}
|
||||
|
||||
func firstIndexOfChars(p string, any []string) (min int, c string) {
|
||||
l := len(p)
|
||||
min = l
|
||||
weight := 0
|
||||
func New(pattern string, d ...string) Glob {
|
||||
chunks := parse(pattern, nil, strings.Join(d, ""))
|
||||
|
||||
for _, s := range any {
|
||||
w := len(s)
|
||||
i := strings.Index(p, s)
|
||||
if i != -1 && i <= min && w > weight {
|
||||
min = i
|
||||
weight = w
|
||||
c = s
|
||||
}
|
||||
if len(chunks) == 1 {
|
||||
return chunks[0]
|
||||
}
|
||||
|
||||
if min == l {
|
||||
return -1, ""
|
||||
}
|
||||
|
||||
return
|
||||
return &composite{chunks}
|
||||
}
|
||||
|
||||
func parse(p string, m []Matcher, d []string) ([]Matcher, error) {
|
||||
func parse(p string, m []Glob, d string) []Glob {
|
||||
if len(p) == 0 {
|
||||
return m, nil
|
||||
return m
|
||||
}
|
||||
|
||||
i, c := firstIndexOfChars(p, Chars)
|
||||
if i == -1 {
|
||||
return append(m, raw{p}), nil
|
||||
return append(m, raw{p})
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
|
@ -65,19 +53,6 @@ func parse(p string, m []Matcher, d []string) ([]Matcher, error) {
|
|||
return parse(p[i+len(c):], m, d)
|
||||
}
|
||||
|
||||
func New(pattern string, d ...string) (Matcher, error) {
|
||||
chunks, err := parse(pattern, nil, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(chunks) == 1 {
|
||||
return chunks[0], nil
|
||||
}
|
||||
|
||||
return &composite{chunks}, nil
|
||||
}
|
||||
|
||||
type raw struct {
|
||||
s string
|
||||
}
|
||||
|
@ -89,39 +64,36 @@ func (self raw) String() string {
|
|||
}
|
||||
|
||||
type multiple struct {
|
||||
delimiters []string
|
||||
delimiters string
|
||||
}
|
||||
|
||||
func (self multiple) Match(s string) bool {
|
||||
i, _ := firstIndexOfChars(s, self.delimiters)
|
||||
return i == -1
|
||||
return strings.IndexAny(s, self.delimiters) == -1
|
||||
}
|
||||
|
||||
func (self multiple) String() string {
|
||||
return fmt.Sprintf("[multiple:%s]", self.delimiters)
|
||||
}
|
||||
|
||||
type single struct {
|
||||
delimiters []string
|
||||
delimiters string
|
||||
}
|
||||
|
||||
func (self single) Match(s string) bool {
|
||||
if len(s) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
i, _ := firstIndexOfChars(s, self.delimiters)
|
||||
|
||||
return i == -1
|
||||
return len(s) == 1 && strings.IndexAny(s, self.delimiters) == -1
|
||||
}
|
||||
|
||||
func (self single) String() string {
|
||||
return fmt.Sprintf("[single:%s]", self.delimiters)
|
||||
}
|
||||
|
||||
type composite struct {
|
||||
chunks []Matcher
|
||||
chunks []Glob
|
||||
}
|
||||
|
||||
|
||||
func (self composite) Match(m string) bool {
|
||||
var prev Matcher
|
||||
var prev Glob
|
||||
|
||||
for _, c := range self.chunks {
|
||||
if str, ok := c.(raw); ok {
|
||||
|
@ -153,3 +125,25 @@ func (self composite) Match(m string) bool {
|
|||
|
||||
return len(m) == 0
|
||||
}
|
||||
|
||||
func firstIndexOfChars(p string, any []string) (min int, c string) {
|
||||
l := len(p)
|
||||
min = l
|
||||
weight := 0
|
||||
|
||||
for _, s := range any {
|
||||
w := len(s)
|
||||
i := strings.Index(p, s)
|
||||
if i != -1 && i <= min && w > weight {
|
||||
min = i
|
||||
weight = w
|
||||
c = s
|
||||
}
|
||||
}
|
||||
|
||||
if min == l {
|
||||
return -1, ""
|
||||
}
|
||||
|
||||
return
|
||||
}
|
18
glob_test.go
18
glob_test.go
|
@ -56,10 +56,12 @@ func TestGlob(t *testing.T) {
|
|||
glob(true, "a.?.c", "a.b.c", "."),
|
||||
glob(true, "a.?.?", "a.b.c", "."),
|
||||
glob(true, "?at", "cat"),
|
||||
glob(true, "?at", "fat"),
|
||||
glob(true, "*", "abc"),
|
||||
glob(true, "**", "a.b.c", "."),
|
||||
|
||||
glob(false, "?at", "at"),
|
||||
glob(false, "?at", "fat", "f"),
|
||||
glob(false, "a.*", "a.b.c", "."),
|
||||
glob(false, "a.?.c", "a.bb.c", "."),
|
||||
glob(false, "*", "a.b.c", "."),
|
||||
|
@ -74,11 +76,7 @@ func TestGlob(t *testing.T) {
|
|||
glob(false, "*is", "this is a test"),
|
||||
glob(false, "*no*", "this is a test"),
|
||||
}{
|
||||
g, err := New(test.pattern, test.delimiters...)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
g := New(test.pattern, test.delimiters...)
|
||||
|
||||
result := g.Match(test.match)
|
||||
if result != test.should {
|
||||
|
@ -91,14 +89,14 @@ func TestGlob(t *testing.T) {
|
|||
const Pattern = "*cat*eyes*"
|
||||
const ExpPattern = ".*cat.*eyes.*"
|
||||
const String = "my cat has very bright eyes"
|
||||
//const Pattern = "*.google.com"
|
||||
//const ExpPattern = ".*google\\.com"
|
||||
//const String = "mail.google.com"
|
||||
|
||||
func BenchmarkGobwas(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
m, err := New(Pattern)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
m := New(Pattern)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(String)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
# glob.[go](https://golang.org)
|
||||
|
||||
Simple globbing library.
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
go get github.com/gobwas/glob
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
|
||||
package main
|
||||
|
||||
import "github.com/gobwas/glob"
|
||||
|
||||
func main() {
|
||||
var g glob.Glob
|
||||
|
||||
// create simple glob
|
||||
g = glob.New("*.github.com")
|
||||
g.Match("api.github.com") // true
|
||||
|
||||
// create new glob with set of delimiters as ["."]
|
||||
g = glob.New("api.*.com", ".")
|
||||
g.Match("api.github.com") // true
|
||||
g.Match("api.gi.hub.com") // false
|
||||
|
||||
// create new glob with set of delimiters as ["."]
|
||||
// but now with super wildcard
|
||||
g = glob.New("api.**.com", ".")
|
||||
g.Match("api.github.com") // true
|
||||
g.Match("api.gi.hub.com") // true
|
||||
|
||||
// create glob with single symbol wildcard
|
||||
g = glob.New("?at")
|
||||
g.Match("cat") // true
|
||||
g.Match("fat") // true
|
||||
g.Match("at") // false
|
||||
|
||||
// create glob with single symbol wildcard and delimiters ["f"]
|
||||
g = glob.New("?at", "f")
|
||||
g.Match("cat") // true
|
||||
g.Match("fat") // false
|
||||
g.Match("at") // false
|
||||
}
|
||||
|
||||
```
|
Loading…
Reference in New Issue