go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/pattern.go (about) 1 package fu 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 /* 9 123textE + *textE -> *TEXT => 123TEXT 10 123textE + 123text* -> TEXT* => TEXTE 11 123textE + *text* -> *TEXT* => 123TEXTE 12 123textE + 123*E -> 55*5 => 55text5 13 14 */ 15 16 func makesubst(subst string) func(string) string { 17 counter := AtomicCounter{1} 18 j := strings.Index(subst, "*") 19 if j < 0 { 20 return func(v string) string { 21 if len(v) == 0 { 22 return subst 23 } 24 return subst + fmt.Sprint(counter.PostInc()) 25 } 26 } 27 if j == 0 { 28 return func(v string) string { return v + subst[1:] } 29 } 30 if j == len(subst)-1 { 31 return func(v string) string { return subst[:j] + v } 32 } 33 return func(v string) string { 34 return subst[:j] + v + subst[j+1:] 35 } 36 } 37 38 func Starsub(pattern, subst string) func(string) (string, bool) { 39 j := strings.Index(pattern, "*") 40 if j < 0 { 41 return func(v string) (string, bool) { 42 if v == pattern { 43 return subst, true 44 } 45 return pattern, false 46 } 47 } 48 if j == 0 { 49 right := pattern[1:] 50 if right[len(right)-1] == '*' { 51 center := right[:len(right)-1] 52 if subst[0] != '*' && subst[len(subst)-1] != '*' { 53 panic("substitution must be like *blablabla*") 54 } 55 subst = subst[1 : len(subst)-1] 56 return func(v string) (string, bool) { 57 if k := strings.Index(v, center); k > 0 { 58 return v[:k] + subst + v[k+len(center):], true 59 } 60 return v, false 61 } 62 } 63 f := makesubst(subst) 64 return func(v string) (string, bool) { 65 if strings.HasSuffix(v, right) { 66 return f(v[:len(v)-len(right)]), true 67 } 68 return v, false 69 } 70 } 71 if j == len(pattern)-1 { 72 left := pattern[:j] 73 f := makesubst(subst) 74 return func(v string) (string, bool) { 75 if strings.HasPrefix(v, left) { 76 return f(v[len(left):]), true 77 } 78 return v, false 79 } 80 } 81 // 123textE + 123*E -> 55*5 => 55text5 82 left := pattern[:j] 83 right := pattern[j+1:] 84 f := makesubst(subst) 85 return func(v string) (string, bool) { 86 if len(v) > len(left)+len(right) && strings.HasPrefix(v, left) && strings.HasSuffix(v, right) { 87 return f(v[len(left) : len(v)-len(right)]), true 88 } 89 return v, false 90 } 91 } 92 93 func Pattern(pattern string) func(string) bool { 94 l := len(pattern) 95 j := strings.Index(pattern, "*") 96 if j < 0 { 97 return func(name string) bool { return name == pattern } 98 } 99 if j == 0 { 100 p := pattern[1:] 101 if p[len(p)-1] == '*' { 102 p := p[:len(p)-1] 103 return func(v string) bool { 104 k := strings.Index(v, p) 105 return k > 0 && k < len(v)-1 106 } 107 } 108 return func(name string) bool { 109 return strings.HasSuffix(name, p) 110 } 111 } 112 if j == l-1 { 113 p := pattern[:j] 114 return func(name string) bool { 115 return strings.HasPrefix(name, p) 116 } 117 } 118 left := pattern[:j] 119 right := pattern[j+1:] 120 return func(name string) bool { 121 return len(name) >= l && 122 strings.HasPrefix(name, left) && 123 strings.HasSuffix(name, right) 124 } 125 }