diff --git a/gjson.go b/gjson.go index 2c9325f..36e858f 100644 --- a/gjson.go +++ b/gjson.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "reflect" + "regexp" "strconv" "strings" "sync" @@ -706,6 +707,8 @@ type arrayPathResult struct { value string all bool } + + re *regexp.Regexp } func parseArrayPath(path string) (r arrayPathResult) { @@ -1098,9 +1101,17 @@ func queryMatches(rp *arrayPathResult, value Result) bool { case ">=": return value.Str >= rpv case "%": - return match.Match(value.Str, rpv) + if rp.re == nil { + rpv = strings.Replace(rpv, `\"`, `"`, -1) + rp.re = regexp.MustCompile(rpv) + } + return rp.re.MatchString(value.Str) case "!%": - return !match.Match(value.Str, rpv) + if rp.re == nil { + rpv = strings.Replace(rpv, `\"`, `"`, -1) + rp.re = regexp.MustCompile(rpv) + } + return !rp.re.MatchString(value.Str) } case Number: rpvn, _ := strconv.ParseFloat(rpv, 64) diff --git a/gjson_test.go b/gjson_test.go index c994cef..a80a84c 100644 --- a/gjson_test.go +++ b/gjson_test.go @@ -390,6 +390,7 @@ func TestBasic1(t *testing.T) { t.Fatalf("expected %v, got %v", 3, count) } } + func TestBasic2(t *testing.T) { mtok := get(basicJSON, `loggy.programmers.#[age=101].firstName`) if mtok.String() != "1002.3" { @@ -399,14 +400,15 @@ func TestBasic2(t *testing.T) { if mtok.String() != "Jason" { t.Fatalf("expected %v, got %v", "Jason", mtok.String()) } - mtok = get(basicJSON, `loggy.programmers.#[firstName % "Bre*"].email`) + mtok = get(basicJSON, `loggy.programmers.#[firstName % "Bre.*"].email`) if mtok.String() != "aaaa" { t.Fatalf("expected %v, got %v", "aaaa", mtok.String()) } - mtok = get(basicJSON, `loggy.programmers.#[firstName !% "Bre*"].email`) + mtok = get(basicJSON, `loggy.programmers.#[firstName !% "Bre.*"].email`) if mtok.String() != "bbbb" { t.Fatalf("expected %v, got %v", "bbbb", mtok.String()) } + mtok = get(basicJSON, `loggy.programmers.#[firstName == "Brett"].email`) if mtok.String() != "aaaa" { t.Fatalf("expected %v, got %v", "aaaa", mtok.String()) @@ -1431,3 +1433,10 @@ func TestArrayValues(t *testing.T) { } } + +func TestEsonRegexp(t *testing.T) { + mtok := get(`{"data": [ {"dat": "123\"", "next": [{"a": "\"32"}, {"a": "32"}]}, {"dat": "234"} ] }`, `data.#[dat % "3\""].next.#[a % "\"32"]#.a`) + if mtok.String() != `["\"32"]` { + t.Fatalf("expected %v, got %v", `"32`, mtok.String()) + } +}