forked from mirror/gjson
unicode patterns
This commit is contained in:
parent
67e38154bd
commit
4fceff029c
86
gjson.go
86
gjson.go
|
@ -485,6 +485,7 @@ func Get(json string, path string) Result {
|
|||
var alogok bool
|
||||
var alogkey string
|
||||
var alog []int
|
||||
var uc bool
|
||||
|
||||
// parse the path into multiple parts.
|
||||
for i := 0; i < len(path); i++ {
|
||||
|
@ -521,6 +522,10 @@ func Get(json string, path string) Result {
|
|||
}
|
||||
continue
|
||||
}
|
||||
if path[i] > 0x7f {
|
||||
uc = true
|
||||
continue
|
||||
}
|
||||
if path[i] == '\\' {
|
||||
// go into escape mode. this is a slower path that
|
||||
// strips off the escape character from the part.
|
||||
|
@ -530,6 +535,10 @@ func Get(json string, path string) Result {
|
|||
epart = append(epart, path[i])
|
||||
i++
|
||||
for ; i < len(path); i++ {
|
||||
if path[i] > 0x7f {
|
||||
uc = true
|
||||
continue
|
||||
}
|
||||
if path[i] == '\\' {
|
||||
i++
|
||||
if i < len(path) {
|
||||
|
@ -682,7 +691,7 @@ read_key:
|
|||
if parts[depth-1].wild {
|
||||
// the path part contains a wildcard character. we must do a wildcard
|
||||
// match to determine if it truly matches.
|
||||
matched = wildcardMatch(f.key, parts[depth-1].key)
|
||||
matched = wildcardMatch(f.key, parts[depth-1].key, uc)
|
||||
} else {
|
||||
// just a straight up equality check
|
||||
matched = parts[depth-1].key == f.key
|
||||
|
@ -1093,12 +1102,24 @@ func stringLessInsensitive(a, b string) bool {
|
|||
// wilcardMatch returns true if str matches pattern. This is a very
|
||||
// simple wildcard match where '*' matches on any number characters
|
||||
// and '?' matches on any one character.
|
||||
func wildcardMatch(str, pattern string) bool {
|
||||
func wildcardMatch(str, pattern string, uc bool) bool {
|
||||
if pattern == "*" {
|
||||
return true
|
||||
}
|
||||
if !uc {
|
||||
return deepMatch(str, pattern)
|
||||
}
|
||||
rstr := make([]rune, 0, len(str))
|
||||
rpattern := make([]rune, 0, len(pattern))
|
||||
for _, r := range str {
|
||||
rstr = append(rstr, r)
|
||||
}
|
||||
for _, r := range pattern {
|
||||
rpattern = append(rpattern, r)
|
||||
}
|
||||
return deepMatchRune(rstr, rpattern)
|
||||
}
|
||||
|
||||
func deepMatch(str, pattern string) bool {
|
||||
for len(pattern) > 0 {
|
||||
switch pattern[0] {
|
||||
|
@ -1111,11 +1132,68 @@ func deepMatch(str, pattern string) bool {
|
|||
return false
|
||||
}
|
||||
case '*':
|
||||
return wildcardMatch(str, pattern[1:]) ||
|
||||
(len(str) > 0 && wildcardMatch(str[1:], pattern))
|
||||
return deepMatch(str, pattern[1:]) ||
|
||||
(len(str) > 0 && deepMatch(str[1:], pattern))
|
||||
}
|
||||
str = str[1:]
|
||||
pattern = pattern[1:]
|
||||
}
|
||||
return len(str) == 0 && len(pattern) == 0
|
||||
}
|
||||
func deepMatchRune(str, pattern []rune) bool {
|
||||
for len(pattern) > 0 {
|
||||
switch pattern[0] {
|
||||
default:
|
||||
if len(str) == 0 || str[0] != pattern[0] {
|
||||
return false
|
||||
}
|
||||
case '?':
|
||||
if len(str) == 0 {
|
||||
return false
|
||||
}
|
||||
case '*':
|
||||
return deepMatchRune(str, pattern[1:]) ||
|
||||
(len(str) > 0 && deepMatchRune(str[1:], pattern))
|
||||
}
|
||||
str = str[1:]
|
||||
pattern = pattern[1:]
|
||||
}
|
||||
return len(str) == 0 && len(pattern) == 0
|
||||
}
|
||||
|
||||
/*
|
||||
func wildcardMatch(str, pattern string) bool {
|
||||
if pattern == "*" {
|
||||
return true
|
||||
}
|
||||
rstr := make([]rune, 0, len(str))
|
||||
rpattern := make([]rune, 0, len(pattern))
|
||||
for _, r := range str {
|
||||
rstr = append(rstr, r)
|
||||
}
|
||||
for _, r := range pattern {
|
||||
rpattern = append(rpattern, r)
|
||||
}
|
||||
return deepMatch(rstr, rpattern)
|
||||
}
|
||||
func deepMatch(str, pattern []rune) bool {
|
||||
for len(pattern) > 0 {
|
||||
switch pattern[0] {
|
||||
default:
|
||||
if len(str) == 0 || str[0] != pattern[0] {
|
||||
return false
|
||||
}
|
||||
case '?':
|
||||
if len(str) == 0 {
|
||||
return false
|
||||
}
|
||||
case '*':
|
||||
return deepMatch(str, pattern[1:]) ||
|
||||
(len(str) > 0 && deepMatch(str[1:], pattern))
|
||||
}
|
||||
str = str[1:]
|
||||
pattern = pattern[1:]
|
||||
}
|
||||
return len(str) == 0 && len(pattern) == 0
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -248,7 +248,71 @@ func TestBasic(t *testing.T) {
|
|||
t.Fatalf("expecting %v, got %v", "Jason", fn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatch(t *testing.T) {
|
||||
if !wildcardMatch("hello world", "hello world", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if wildcardMatch("hello world", "jello world", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("hello world", "hello*", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if wildcardMatch("hello world", "jello*", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("hello world", "hello?world", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if wildcardMatch("hello world", "jello?world", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("hello world", "he*o?world", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("hello world", "he*o?wor*", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("hello world", "he*o?*r*", false) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("的情况下解析一个", "*", true) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("的情况下解析一个", "*况下*", true) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("的情况下解析一个", "*况?*", true) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if !wildcardMatch("的情况下解析一个", "的情况?解析一个", true) {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
}
|
||||
func TestUnicode(t *testing.T) {
|
||||
var json = `{"key":0,"的情况下解":{"key":1,"的情况":2}}`
|
||||
if Get(json, "的情况下解.key").Num != 1 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if Get(json, "的情况下解.的情况").Num != 2 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if Get(json, "的情况下解.的?况").Num != 2 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if Get(json, "的情况下解.的?*").Num != 2 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if Get(json, "的情况下解.*?况").Num != 2 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if Get(json, "的情?下解.*?况").Num != 2 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
if Get(json, "的情下解.*?况").Num != 0 {
|
||||
t.Fatal("fail")
|
||||
}
|
||||
}
|
||||
func TestUnescape(t *testing.T) {
|
||||
unescape(string([]byte{'\\', '\\', 0}))
|
||||
unescape(string([]byte{'\\', '/', '\\', 'b', '\\', 'f'}))
|
||||
|
|
Loading…
Reference in New Issue