<commit_before># Jsonpath

This is an implementation of http://goessner.net/articles/JsonPath/. 

## Usage

There is stand-alone usage through the binary `jsonpath`

    jsonpath [expression] (file|string)

    If you omit the second argument, it will read stdin, assuming one valid JSON object
    per line. Expression must be a valid jsonpath expression.

As well, you can include it as a library.

~~~~~ {ruby}
    object = JSON.parse(<<-HERE_DOC)
    {"store": 
      {"bicycle":
        {"price":19.95, "color":"red"},
        "book":[
          {"price":8.95, "category":"reference", "title":"Sayings of the Century", "author":"<NAME>"},
          {"price":12.99, "category":"fiction", "title":"Sword of Honour", "author":"<NAME>"},
          {"price":8.99, "category":"fiction", "isbn":"0-553-21311-3", "title":"Moby Dick", "author":"<NAME>"},
          {"price":22.99, "category":"fiction", "isbn":"0-395-19395-8", "title":"The Lord of the Rings", "author":"<NAME>"}
        ]
      }
    }
    HERE_DOC

    JsonPath.new('$..price').on(object)
    # => [19.95, 8.95, 12.99, 8.99, 22.99]
  
    JsonPath.on(object, '$..author')
    # => ["<NAME>", "<NAME>", "<NAME>", "<NAME>"]
  
    JsonPath.new('$..book[::2]').on(object)
    # => [{"price"=>8.95, "category"=>"reference", "author"=>"<NAME>", "title"=>"Sayings of the Century"}, {"price"=>8.99, "category"=>"fiction", "author"=>"<NAME>", "title"=>"Moby Dick", "isbn"=>"0-553-21311-3"}]

    JsonPath.new('$..color').first(object)
    # => "red"

    # Lazy enumeration - only needs to find the first two matches
    JsonPath.new('$..price').enum_on(object).each do |match|
      break price if price < 15.0
    end
    # => 8.95
~~~~~

You can optionally prevent eval from being called on sub-expressions by passing in :allow_eval => false to the constructor.

If you'd like to do substitution in a json object, do this:
    JsonPath.for({'test' => 'time'}).gsub('$..test') {|v| v << v}

The result will be
    {'test' => 'timetime'}<commit_msg>fix formatting<commit_after># Jsonpath

This is an implementation of http://goessner.net/articles/JsonPath/. 

## Usage

There is stand-alone usage through the binary `jsonpath`

    jsonpath [expression] (file|string)

    If you omit the second argument, it will read stdin, assuming one valid JSON object
    per line. Expression must be a valid jsonpath expression.

As well, you can include it as a library.

~~~~~ {ruby}
    object = JSON.parse(<<-HERE_DOC)
    {"store": 
      {"bicycle":
        {"price":19.95, "color":"red"},
        "book":[
          {"price":8.95, "category":"reference", "title":"Sayings of the Century", "author":"<NAME>"},
          {"price":12.99, "category":"fiction", "title":"Sword of Honour", "author":"<NAME>"},
          {"price":8.99, "category":"fiction", "isbn":"0-553-21311-3", "title":"Moby Dick", "author":"<NAME>"},
          {"price":22.99, "category":"fiction", "isbn":"0-395-19395-8", "title":"The Lord of the Rings", "author":"<NAME>"}
        ]
      }
    }
    HERE_DOC

    JsonPath.new('$..price').on(object)
    # => [19.95, 8.95, 12.99, 8.99, 22.99]
  
    JsonPath.on(object, '$..author')
    # => ["<NAME>", "<NAME>", "<NAME>", "<NAME>"]
  
    JsonPath.new('$..book[::2]').on(object)
    # => [{"price"=>8.95, "category"=>"reference", "author"=>"<NAME>", "title"=>"Sayings of the Century"}, {"price"=>8.99, "category"=>"fiction", "author"=>"<NAME>", "title"=>"Moby Dick", "isbn"=>"0-553-21311-3"}]

    JsonPath.new('$..color').first(object)
    # => "red"

    # Lazy enumeration - only needs to find the first two matches
    JsonPath.new('$..price').enum_on(object).each do |match|
      break price if price < 15.0
    end
    # => 8.95
~~~~~

You can optionally prevent eval from being called on sub-expressions by passing in :allow_eval => false to the constructor.

If you'd like to do substitution in a json object, do this:

~~~~~ {ruby}
    JsonPath.for({'test' => 'time'}).gsub('$..test') {|v| v << v}

The result will be

~~~~~ {ruby}
    {'test' => 'timetime'}
{'fraction_non_alphanumeric': 0.21529324424647364, 'fraction_numerical': 0.039099232863152686, 'mean_word_length': 3.432017543859649, 'pattern_counts': {'":': 46, '<': 33, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '392295', 'n_tokens_mistral': 1499, 'n_tokens_neox': 1365, 'n_words': 360}