Skip to content

Commit 7ec50e6

Browse files
grosserGergely Brautigam
andauthored
remove to_regex dependency and the warnings it causes (#128)
Co-authored-by: Gergely Brautigam <gergely@arangodb.com>
1 parent ccfb39b commit 7ec50e6

2 files changed

Lines changed: 37 additions & 14 deletions

File tree

jsonpath.gemspec

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ require File.join(File.dirname(__FILE__), 'lib', 'jsonpath', 'version')
55
Gem::Specification.new do |s|
66
s.name = 'jsonpath'
77
s.version = JsonPath::VERSION
8-
s.required_rubygems_version = Gem::Requirement.new('>= 0')
98
s.required_ruby_version = '>= 2.5'
109
s.authors = ['Joshua Hull', 'Gergely Brautigam']
1110
s.summary = 'Ruby implementation of http://goessner.net/articles/JsonPath/'
@@ -14,17 +13,12 @@ Gem::Specification.new do |s|
1413
s.extra_rdoc_files = ['README.md']
1514
s.files = `git ls-files`.split("\n")
1615
s.homepage = 'https://github.com/joshbuddy/jsonpath'
17-
s.rdoc_options = ['--charset=UTF-8']
18-
s.require_paths = ['lib']
19-
s.rubygems_version = '1.3.7'
2016
s.test_files = `git ls-files`.split("\n").select { |f| f =~ /^spec/ }
21-
s.rubyforge_project = 'jsonpath'
2217
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
2318
s.licenses = ['MIT']
2419

2520
# dependencies
2621
s.add_runtime_dependency 'multi_json'
27-
s.add_runtime_dependency 'to_regexp', '~> 0.2.1'
2822
s.add_development_dependency 'bundler'
2923
s.add_development_dependency 'code_stats'
3024
s.add_development_dependency 'minitest', '~> 2.2.0'

lib/jsonpath/parser.rb

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# frozen_string_literal: true
22

33
require 'strscan'
4-
require 'to_regexp'
54

65
class JsonPath
76
# Parser parses and evaluates an expression passed to @_current_node.
87
class Parser
8+
REGEX = /\A\/(.+)\/([imxnesu]*)\z|\A%r{(.+)}([imxnesu]*)\z/
9+
910
def initialize(node)
1011
@_current_node = node
1112
@_expr_map = {}
@@ -71,13 +72,16 @@ def parse_exp(exp)
7172
elsif (t = scanner.scan(/(\s+)?'?.*'?(\s+)?/))
7273
# If we encounter a node which does not contain `'` it means
7374
#  that we are dealing with a boolean type.
74-
operand = if t == 'true'
75-
true
76-
elsif t == 'false'
77-
false
78-
else
79-
operator.to_s.strip == '=~' ? t.to_regexp : t.gsub(%r{^'|'$}, '').strip
80-
end
75+
operand =
76+
if t == 'true'
77+
true
78+
elsif t == 'false'
79+
false
80+
elsif operator.to_s.strip == '=~'
81+
parse_regex(t)
82+
else
83+
t.gsub(%r{^'|'$}, '').strip
84+
end
8185
elsif (t = scanner.scan(/\/\w+\//))
8286
elsif (t = scanner.scan(/.*/))
8387
raise "Could not process symbol: #{t}"
@@ -102,6 +106,31 @@ def parse_exp(exp)
102106

103107
private
104108

109+
# /foo/i -> Regex.new("foo", Regexp::IGNORECASE) without using eval
110+
# also supports %r{foo}i
111+
# following https://github.com/seamusabshere/to_regexp/blob/master/lib/to_regexp.rb
112+
def parse_regex(t)
113+
t =~ REGEX
114+
content = $1 || $3
115+
options = $2 || $4
116+
117+
raise "unsupported regex #{t} use /foo/ style" if !content || !options
118+
119+
content = content.gsub '\\/', '/'
120+
121+
flags = 0
122+
flags |= Regexp::IGNORECASE if options.include?('i')
123+
flags |= Regexp::MULTILINE if options.include?('m')
124+
flags |= Regexp::EXTENDED if options.include?('x')
125+
126+
# 'n' = none, 'e' = EUC, 's' = SJIS, 'u' = UTF-8
127+
lang = options.scan(/[nes]/).join.downcase # ignores u since that is default and causes a warning
128+
129+
args = [content, flags]
130+
args << lang unless lang.empty? # avoid warning
131+
Regexp.new(*args)
132+
end
133+
105134
#  This will break down a parenthesis from the left to the right
106135
#  and replace the given expression with it's returned value.
107136
# It does this in order to make it easy to eliminate groups

0 commit comments

Comments
 (0)