| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- package main
- import (
- //"fmt"
- "path"
- "strings"
- "unicode/utf8"
- "regexp"
- )
- var ErrBadPattern = path.ErrBadPattern
- func main(){
-
- match, _ := ExpMatch("linux*","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux.*?","linux1")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("linux?","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux.","linux1")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("linux[1-2]","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux[1-2]","linux1")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("linux[12]","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux[12]","linux1")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("linux[^2345]","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux[^2345]","linux1")
- println("regexp ==>", match)
- println("----------------------")
-
- match, _ = ExpMatch("linux[^12345]","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux[^12345]","linux1")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("linux*[^12345]","linux1")
- println(match)
-
- match, _ = regexp.MatchString("linux.*?[^12345]","linux1")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("中文*","中文测试")
- println(match)
-
- match, _ = regexp.MatchString("中文*","中文测试")
- println("regexp ==>", match)
-
- match, _ = ExpMatch("中文??","中文测试")
- println(match)
-
- match, _ = regexp.MatchString("中文..","中文测试")
- println("regexp ==>", match)
-
- srp := strings.NewReplacer("?", ".", "*", ".*?")
- s := "linux*?"
- print( "replace ==>", srp.Replace(s) )
-
- }
- func ExpMatch(pattern, name string) (bool, error) {
- // check some base cases
- patternLen, nameLen := len(pattern), len(name)
- if patternLen == 0 && nameLen == 0 {
- return true, nil
- }
- if patternLen == 0 {
- return false, nil
- }
- if nameLen == 0 && pattern != "*" {
- return false, nil
- }
- // check for matches one rune at a time
- patIdx, nameIdx := 0, 0
- for patIdx < patternLen && nameIdx < nameLen {
- patRune, patAdj := utf8.DecodeRuneInString(pattern[patIdx:])
- nameRune, nameAdj := utf8.DecodeRuneInString(name[nameIdx:])
- if patRune == '\\' {
- // handle escaped runes
- patIdx += patAdj
- patRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:])
- if patRune == utf8.RuneError {
- return false, ErrBadPattern
- } else if patRune == nameRune {
- patIdx += patAdj
- nameIdx += nameAdj
- } else {
- return false, nil
- }
- } else if patRune == '*' {
- // handle stars
- if patIdx += patAdj; patIdx >= patternLen {
- // a star at the end of a pattern will always
- // match the rest of the path
- return true, nil
- }
- // check if we can make any matches
- for ; nameIdx < nameLen; nameIdx += nameAdj {
- if m, _ := ExpMatch(pattern[patIdx:], name[nameIdx:]); m {
- return true, nil
- }
- }
- return false, nil
- } else if patRune == '[' {
- // handle character sets
- patIdx += patAdj
- endClass := indexRuneWithEscaping(pattern[patIdx:], ']')
- if endClass == -1 {
- return false, ErrBadPattern
- }
- endClass += patIdx
- classRunes := []rune(pattern[patIdx:endClass])
- classRunesLen := len(classRunes)
- if classRunesLen > 0 {
- classIdx := 0
- matchClass := false
- if classRunes[0] == '^' {
- classIdx++
- }
- for classIdx < classRunesLen {
- low := classRunes[classIdx]
- if low == '-' {
- return false, ErrBadPattern
- }
- classIdx++
- if low == '\\' {
- if classIdx < classRunesLen {
- low = classRunes[classIdx]
- classIdx++
- } else {
- return false, ErrBadPattern
- }
- }
- high := low
- if classIdx < classRunesLen && classRunes[classIdx] == '-' {
- // we have a range of runes
- if classIdx++; classIdx >= classRunesLen {
- return false, ErrBadPattern
- }
- high = classRunes[classIdx]
- if high == '-' {
- return false, ErrBadPattern
- }
- classIdx++
- if high == '\\' {
- if classIdx < classRunesLen {
- high = classRunes[classIdx]
- classIdx++
- } else {
- return false, ErrBadPattern
- }
- }
- }
- if low <= nameRune && nameRune <= high {
- matchClass = true
- }
- }
- if matchClass == (classRunes[0] == '^') {
- return false, nil
- }
- } else {
- return false, ErrBadPattern
- }
- patIdx = endClass + 1
- nameIdx += nameAdj
- }else if patRune == '?' || patRune == nameRune {
- // handle single-rune wildcard
- patIdx += patAdj
- nameIdx += nameAdj
- } else {
- return false, nil
- }
- }
- if patIdx >= patternLen && nameIdx >= nameLen {
- return true, nil
- }
- if nameIdx >= nameLen && pattern[patIdx:] == "*" || pattern[patIdx:] == "**" {
- return true, nil
- }
- return false, nil
- }
- // Find the first index of a rune in a string,
- // ignoring any times the rune is escaped using "\".
- func indexRuneWithEscaping(s string, r rune) int {
- end := strings.IndexRune(s, r)
- if end == -1 {
- return -1
- }
- if end > 0 && s[end-1] == '\\' {
- start := end + utf8.RuneLen(r)
- end = indexRuneWithEscaping(s[start:], r)
- if end != -1 {
- end += start
- }
- }
- return end
- }
|