Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
862cbc6b80 | |||
013383b188 | |||
fdedd9ddb2 | |||
8ca66dad60 |
55
gjson.go
55
gjson.go
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -706,6 +707,8 @@ type arrayPathResult struct {
|
|||||||
value string
|
value string
|
||||||
all bool
|
all bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
re *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseArrayPath(path string) (r arrayPathResult) {
|
func parseArrayPath(path string) (r arrayPathResult) {
|
||||||
@ -741,6 +744,7 @@ func parseArrayPath(path string) (r arrayPathResult) {
|
|||||||
path[i] == '<' ||
|
path[i] == '<' ||
|
||||||
path[i] == '>' ||
|
path[i] == '>' ||
|
||||||
path[i] == '%' ||
|
path[i] == '%' ||
|
||||||
|
path[i] == '~' ||
|
||||||
path[i] == ']' {
|
path[i] == ']' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -776,7 +780,34 @@ func parseArrayPath(path string) (r arrayPathResult) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = i
|
s = i + 1
|
||||||
|
|
||||||
|
if r.query.op == "~" {
|
||||||
|
pair := path[i]
|
||||||
|
i++
|
||||||
|
GETREGEXPSTR:
|
||||||
|
for ; i < len(path); i++ {
|
||||||
|
if path[i] == pair {
|
||||||
|
for iend := i + 1; iend < len(path); iend++ {
|
||||||
|
|
||||||
|
if path[iend] == ' ' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if path[iend] == ']' {
|
||||||
|
if iend+1 < len(path) && path[iend+1] == '#' {
|
||||||
|
r.query.all = true
|
||||||
|
}
|
||||||
|
break GETREGEXPSTR
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
for ; i < len(path); i++ {
|
for ; i < len(path); i++ {
|
||||||
if path[i] == '"' {
|
if path[i] == '"' {
|
||||||
i++
|
i++
|
||||||
@ -808,6 +839,7 @@ func parseArrayPath(path string) (r arrayPathResult) {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} //
|
||||||
}
|
}
|
||||||
if i > len(path) {
|
if i > len(path) {
|
||||||
i = len(path)
|
i = len(path)
|
||||||
@ -1077,6 +1109,22 @@ func parseObject(c *parseContext, i int, path string) (int, bool) {
|
|||||||
}
|
}
|
||||||
return i, false
|
return i, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func escapeRegexpString(rpv string) string {
|
||||||
|
var content []byte
|
||||||
|
lrpv := len(rpv)
|
||||||
|
for i := 0; i < lrpv; i++ {
|
||||||
|
rpvChar := rpv[i]
|
||||||
|
if rpvChar == '\\' {
|
||||||
|
content = append(content, rpv[i+1])
|
||||||
|
i++
|
||||||
|
} else {
|
||||||
|
content = append(content, rpvChar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(content)
|
||||||
|
}
|
||||||
|
|
||||||
func queryMatches(rp *arrayPathResult, value Result) bool {
|
func queryMatches(rp *arrayPathResult, value Result) bool {
|
||||||
rpv := rp.query.value
|
rpv := rp.query.value
|
||||||
if len(rpv) > 2 && rpv[0] == '"' && rpv[len(rpv)-1] == '"' {
|
if len(rpv) > 2 && rpv[0] == '"' && rpv[len(rpv)-1] == '"' {
|
||||||
@ -1101,6 +1149,11 @@ func queryMatches(rp *arrayPathResult, value Result) bool {
|
|||||||
return match.Match(value.Str, rpv)
|
return match.Match(value.Str, rpv)
|
||||||
case "!%":
|
case "!%":
|
||||||
return !match.Match(value.Str, rpv)
|
return !match.Match(value.Str, rpv)
|
||||||
|
case "~":
|
||||||
|
if rp.re == nil {
|
||||||
|
rp.re = regexp.MustCompile(rpv)
|
||||||
|
}
|
||||||
|
return rp.re.MatchString(value.Str)
|
||||||
}
|
}
|
||||||
case Number:
|
case Number:
|
||||||
rpvn, _ := strconv.ParseFloat(rpv, 64)
|
rpvn, _ := strconv.ParseFloat(rpv, 64)
|
||||||
|
@ -390,6 +390,7 @@ func TestBasic1(t *testing.T) {
|
|||||||
t.Fatalf("expected %v, got %v", 3, count)
|
t.Fatalf("expected %v, got %v", 3, count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasic2(t *testing.T) {
|
func TestBasic2(t *testing.T) {
|
||||||
mtok := get(basicJSON, `loggy.programmers.#[age=101].firstName`)
|
mtok := get(basicJSON, `loggy.programmers.#[age=101].firstName`)
|
||||||
if mtok.String() != "1002.3" {
|
if mtok.String() != "1002.3" {
|
||||||
@ -399,14 +400,15 @@ func TestBasic2(t *testing.T) {
|
|||||||
if mtok.String() != "Jason" {
|
if mtok.String() != "Jason" {
|
||||||
t.Fatalf("expected %v, got %v", "Jason", mtok.String())
|
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" {
|
if mtok.String() != "aaaa" {
|
||||||
t.Fatalf("expected %v, got %v", "aaaa", mtok.String())
|
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" {
|
if mtok.String() != "bbbb" {
|
||||||
t.Fatalf("expected %v, got %v", "bbbb", mtok.String())
|
t.Fatalf("expected %v, got %v", "bbbb", mtok.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
mtok = get(basicJSON, `loggy.programmers.#[firstName == "Brett"].email`)
|
mtok = get(basicJSON, `loggy.programmers.#[firstName == "Brett"].email`)
|
||||||
if mtok.String() != "aaaa" {
|
if mtok.String() != "aaaa" {
|
||||||
t.Fatalf("expected %v, got %v", "aaaa", mtok.String())
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user