66 "go/token"
77 "go/types"
88 "reflect"
9+ "regexp"
910 "strconv"
1011 "strings"
1112)
@@ -78,6 +79,9 @@ func JsonPathLookup(obj interface{}, jpath string) (interface{}, error) {
7879 return nil , err
7980 }
8081 obj , err = get_filtered (obj , obj , args .(string ))
82+ if err != nil {
83+ return nil , err
84+ }
8185 default :
8286 return nil , fmt .Errorf ("expression don't support in filter" )
8387 }
@@ -365,6 +369,19 @@ func get_range(obj, frm, to interface{}) (interface{}, error) {
365369 }
366370}
367371
372+ func regFilterCompile (rule string ) (* regexp.Regexp , error ) {
373+ runes := []rune (rule )
374+ if len (runes ) <= 2 {
375+ return nil , errors .New ("empty rule" )
376+ }
377+
378+ if runes [0 ] != '/' || runes [len (runes )- 1 ] != '/' {
379+ return nil , errors .New ("invalid syntax. should be in `/pattern/` form" )
380+ }
381+ runes = runes [1 : len (runes )- 1 ]
382+ return regexp .Compile (string (runes ))
383+ }
384+
368385func get_filtered (obj , root interface {}, filter string ) ([]interface {}, error ) {
369386 lp , op , rp , err := parse_filter (filter )
370387 if err != nil {
@@ -375,26 +392,64 @@ func get_filtered(obj, root interface{}, filter string) ([]interface{}, error) {
375392
376393 switch reflect .TypeOf (obj ).Kind () {
377394 case reflect .Slice :
378- for i := 0 ; i < reflect . ValueOf ( obj ). Len (); i ++ {
379- tmp := reflect . ValueOf ( obj ). Index ( i ). Interface ()
380- ok , err := eval_filter ( tmp , root , lp , op , rp )
395+ if op == "=~" {
396+ // regexp
397+ pat , err := regFilterCompile ( rp )
381398 if err != nil {
382399 return nil , err
383400 }
384- if ok == true {
385- res = append (res , tmp )
401+
402+ for i := 0 ; i < reflect .ValueOf (obj ).Len (); i ++ {
403+ tmp := reflect .ValueOf (obj ).Index (i ).Interface ()
404+ ok , err := eval_reg_filter (tmp , root , lp , pat )
405+ if err != nil {
406+ return nil , err
407+ }
408+ if ok == true {
409+ res = append (res , tmp )
410+ }
411+ }
412+ } else {
413+ for i := 0 ; i < reflect .ValueOf (obj ).Len (); i ++ {
414+ tmp := reflect .ValueOf (obj ).Index (i ).Interface ()
415+ ok , err := eval_filter (tmp , root , lp , op , rp )
416+ if err != nil {
417+ return nil , err
418+ }
419+ if ok == true {
420+ res = append (res , tmp )
421+ }
386422 }
387423 }
388424 return res , nil
389425 case reflect .Map :
390- for _ , kv := range reflect . ValueOf ( obj ). MapKeys () {
391- tmp := reflect . ValueOf ( obj ). MapIndex ( kv ). Interface ()
392- ok , err := eval_filter ( tmp , root , lp , op , rp )
426+ if op == "=~" {
427+ // regexp
428+ pat , err := regFilterCompile ( rp )
393429 if err != nil {
394430 return nil , err
395431 }
396- if ok == true {
397- res = append (res , tmp )
432+
433+ for _ , kv := range reflect .ValueOf (obj ).MapKeys () {
434+ tmp := reflect .ValueOf (obj ).MapIndex (kv ).Interface ()
435+ ok , err := eval_reg_filter (tmp , root , lp , pat )
436+ if err != nil {
437+ return nil , err
438+ }
439+ if ok == true {
440+ res = append (res , tmp )
441+ }
442+ }
443+ } else {
444+ for _ , kv := range reflect .ValueOf (obj ).MapKeys () {
445+ tmp := reflect .ValueOf (obj ).MapIndex (kv ).Interface ()
446+ ok , err := eval_filter (tmp , root , lp , op , rp )
447+ if err != nil {
448+ return nil , err
449+ }
450+ if ok == true {
451+ res = append (res , tmp )
452+ }
398453 }
399454 }
400455 default :
@@ -507,18 +562,36 @@ func parse_filter_v1(filter string) (lp string, op string, rp string, err error)
507562 return lp , op , rp , err
508563}
509564
510- func eval_filter (obj , root interface {}, lp , op , rp string ) (res bool , err error ) {
565+ func eval_reg_filter (obj , root interface {}, lp string , pat * regexp.Regexp ) (res bool , err error ) {
566+ if pat == nil {
567+ return false , errors .New ("nil pat" )
568+ }
569+ lp_v , err := get_lp_v (obj , root , lp )
570+ if err != nil {
571+ return false , err
572+ }
573+ switch v := lp_v .(type ) {
574+ case string :
575+ return pat .MatchString (v ), nil
576+ default :
577+ return false , errors .New ("only string can match with regular expression" )
578+ }
579+ }
580+
581+ func get_lp_v (obj , root interface {}, lp string ) (interface {}, error ) {
511582 var lp_v interface {}
512- //fmt.Println(obj, root)
513- //fmt.Printf("lp: %v, op: %v, rp: %v\n", lp, op, rp)
514583 if strings .HasPrefix (lp , "@." ) {
515- //fmt.Println("@. ----------------")
516- lp_v , err = filter_get_from_explicit_path (obj , lp )
584+ return filter_get_from_explicit_path (obj , lp )
517585 } else if strings .HasPrefix (lp , "$." ) {
518- lp_v , err = filter_get_from_explicit_path (root , lp )
586+ return filter_get_from_explicit_path (root , lp )
519587 } else {
520588 lp_v = lp
521589 }
590+ return lp_v , nil
591+ }
592+
593+ func eval_filter (obj , root interface {}, lp , op , rp string ) (res bool , err error ) {
594+ lp_v , err := get_lp_v (obj , root , lp )
522595
523596 if op == "exists" {
524597 return lp_v != nil , nil
0 commit comments