35
35
question_path = [" data" , " question" ]
36
36
answers_path = [" data" , " answers" , (0 ..- 1 )]
37
37
json_str = ' {"data": {"question": "the Ultimate Question of Life, the Universe, and Everything", "answers": [42, 0, 420]}}'
38
- questions_pos, answers_pos = JsonScanner .scan(json_str, [question_path, answers_path])
39
- question_pos = questions_pos.first
38
+ (question_pos, ), answers_pos = JsonScanner .scan(json_str, [question_path, answers_path])
40
39
question = JSON .parse(json_str.byteslice(question_pos[0 ]...question_pos[1 ]), quirks_mode: true )
41
40
# => "the Ultimate Question of Life, the Universe, and Everything"
42
- answers = answers_pos.map { |begin_pos , end_pos , _type | JSON .parse(json_str.byteslice(begin_pos...end_pos), quirks_mode: true ) }
41
+ answers = answers_pos.map do |begin_pos , end_pos , _type |
42
+ JSON .parse(json_str.byteslice(begin_pos...end_pos), quirks_mode: true )
43
+ end
43
44
# => [42, 0, 420]
44
45
45
46
# Result contains byte offsets, you need to be careful when working with non-binary strings
46
47
emoji_json = ' {"grin": "😁", "heart": "😍", "rofl": "🤣"}'
47
48
begin_pos, end_pos, = JsonScanner .scan(emoji_json, [[" heart" ]]).first.first
48
49
emoji_json.byteslice(begin_pos...end_pos)
49
50
# => "\"😍\""
50
- # Note: You most likely don't need the `quirks_mode` option unless you are using an older version
51
- # of Ruby with the stdlib - or just also old - version of the json gem. In newer versions, `quirks_mode` is enabled by default.
51
+ # Note: You most likely don't need the `quirks_mode` option unless you are using
52
+ # an older version of Ruby with the stdlib - or just also old - version of the json gem.
53
+ # In newer versions, `quirks_mode` is enabled by default.
52
54
JSON .parse(emoji_json.byteslice(begin_pos...end_pos), quirks_mode: true )
53
55
# => "😍"
54
56
# You can also do this
@@ -102,15 +104,21 @@ JsonScanner.scan('[0, /* answer */ 42, 0]', [[(1..-1)]], allow_comments: true)
102
104
# => [[[17, 19, :number], [21, 22, :number]]]
103
105
JsonScanner .scan(" \"\x81\x83\" " , [[]], dont_validate_strings: true )
104
106
# => [[[0, 4, :string]]]
105
- JsonScanner .scan(" {\"\x81\x83\" : 42}" , [[JsonScanner ::ANY_KEY ]], dont_validate_strings: true , with_path: true )
107
+ JsonScanner .scan(
108
+ " {\"\x81\x83\" : 42}" , [[JsonScanner ::ANY_KEY ]],
109
+ dont_validate_strings: true , with_path: true .
110
+ )
106
111
# => [[[["\x81\x83"], [7, 9, :number]]]]
107
112
JsonScanner .scan(' [0, 42, 0]garbage' , [[(1 ..- 1 )]], allow_trailing_garbage: true )
108
113
# => [[[4, 6, :number], [8, 9, :number]]]
109
114
JsonScanner .scan(' [0, 42, 0] [0, 34]' , [[(1 ..- 1 )]], allow_multiple_values: true )
110
115
# => [[[4, 6, :number], [8, 9, :number], [16, 18, :number]]]
111
116
JsonScanner .scan(' [0, 42, 0' , [[(1 ..- 1 )]], allow_partial_values: true )
112
117
# => [[[4, 6, :number], [8, 9, :number]]]
113
- JsonScanner .scan(' {"a": 1}' , [[JsonScanner ::ANY_KEY ]], with_path: true , symbolize_path_keys: true )
118
+ JsonScanner .scan(
119
+ ' {"a": 1}' , [[JsonScanner ::ANY_KEY ]],
120
+ with_path: true , symbolize_path_keys: true ,
121
+ )
114
122
# => [[[[:a], [6, 7, :number]]]]
115
123
```
116
124
@@ -119,7 +127,9 @@ JsonScanner.scan('{"a": 1}', [[JsonScanner::ANY_KEY]], with_path: true, symboliz
119
127
Note that the standard ` JSON ` library supports comments, so you may want to enable it in the ` JsonScanner ` as well
120
128
``` ruby
121
129
json_str = ' {"answer": {"value": 42 /* the Ultimate Question of Life, the Universe, and Everything */ }}'
122
- JsonScanner .scan(json_str, [[" answer" ]], allow_comments: true ).first.map do |begin_pos , end_pos , _type |
130
+ JsonScanner .scan(
131
+ json_str, [[" answer" ]], allow_comments: true .
132
+ ).first.map do |begin_pos , end_pos , _type |
123
133
JSON .parse(json_str.byteslice(begin_pos...end_pos), quirks_mode: true )
124
134
end
125
135
# => [{"value"=>42}]
@@ -133,7 +143,9 @@ script_text = <<~'JS'
133
143
< script> window .__APOLLO_STATE__ = {" ContentItem:0" : {" __typename" : " ContentItem" ," id" : 0 , " configurationType" : " NO_CONFIGURATION" ," replacementPartsUrl" : null ," relatedCategories" : [{" __ref" : " Category:109450" },{" __ref" : " Category:82044355" },{" __ref" : " Category:109441" },{" __ref" : " Category:109442" },{" __ref" : " Category:109449" },{" __ref" : " Category:109444" },{" __ref" : " Category:82043730" }]," recommendedOptions" : []}};window .__APPVERSION__ = 7018 ;window .__CONFIG_ENV__ = {value: ' PRODUCTION' };< / script>
134
144
JS
135
145
json_with_trailing_garbage = script_text[/__APOLLO_STATE__\s *=\s *({.+) / , 1 ]
136
- json_end_pos = JsonScanner .scan(json_with_trailing_garbage, [[]], allow_trailing_garbage: true ).first.first[1 ]
146
+ json_end_pos = JsonScanner .scan(
147
+ json_with_trailing_garbage, [[]], allow_trailing_garbage: true ,
148
+ ).first.first[1 ]
137
149
apollo_state = JSON .parse(json_with_trailing_garbage[0 ...json_end_pos])
138
150
```
139
151
0 commit comments