diff --git a/README.md b/README.md index 70240d9..a7484c6 100644 --- a/README.md +++ b/README.md @@ -88,13 +88,14 @@ The dot and wildcard characters can be escaped with '\\'. ``` You can also query an array for the first match by using `#[...]`, or find all matches with `#[...]#`. -Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` comparison operators and the simple pattern matching `%` operator. +Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` comparison operators and the simple pattern matching `%` (like) and `!%` (not like) operators. ``` friends.#[last=="Murphy"].first >> "Dale" friends.#[last=="Murphy"]#.first >> ["Dale","Jane"] friends.#[age>45]#.last >> ["Craig","Murphy"] friends.#[first%"D*"].last >> "Murphy" +friends.#[first!%"D*"].last >> "Craig" ``` ## JSON Lines diff --git a/gjson.go b/gjson.go index 418da5d..2c9325f 100644 --- a/gjson.go +++ b/gjson.go @@ -755,7 +755,7 @@ func parseArrayPath(path string) (r arrayPathResult) { if i < len(path) { s = i if path[i] == '!' { - if i < len(path)-1 && path[i+1] == '=' { + if i < len(path)-1 && (path[i+1] == '=' || path[i+1] == '%') { i++ } } else if path[i] == '<' || path[i] == '>' { @@ -1099,6 +1099,8 @@ func queryMatches(rp *arrayPathResult, value Result) bool { return value.Str >= rpv case "%": return match.Match(value.Str, rpv) + case "!%": + return !match.Match(value.Str, rpv) } case Number: rpvn, _ := strconv.ParseFloat(rpv, 64) diff --git a/gjson_test.go b/gjson_test.go index 6333be7..c994cef 100644 --- a/gjson_test.go +++ b/gjson_test.go @@ -403,6 +403,10 @@ func TestBasic2(t *testing.T) { if mtok.String() != "aaaa" { t.Fatalf("expected %v, got %v", "aaaa", mtok.String()) } + 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())