re2 0.7.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +35 -19
- data/Rakefile +4 -9
- data/ext/re2/extconf.rb +62 -19
- data/ext/re2/re2.cc +55 -16
- data/spec/kernel_spec.rb +4 -6
- data/spec/re2/match_data_spec.rb +88 -52
- data/spec/re2/regexp_spec.rb +94 -96
- data/spec/re2/scanner_spec.rb +128 -20
- data/spec/re2/string_spec.rb +12 -13
- data/spec/re2_spec.rb +15 -19
- data/spec/spec_helper.rb +18 -2
- metadata +12 -14
data/spec/re2/scanner_spec.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
describe RE2::Scanner do
|
3
|
+
RSpec.describe RE2::Scanner do
|
4
4
|
describe "#regexp" do
|
5
5
|
it "returns the original pattern for the scanner" do
|
6
6
|
re = RE2::Regexp.new('(\w+)')
|
7
7
|
scanner = re.scan("It is a truth")
|
8
8
|
|
9
|
-
scanner.regexp.
|
9
|
+
expect(scanner.regexp).to equal(re)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -16,7 +16,7 @@ describe RE2::Scanner do
|
|
16
16
|
text = "It is a truth"
|
17
17
|
scanner = re.scan(text)
|
18
18
|
|
19
|
-
scanner.string.
|
19
|
+
expect(scanner.string).to equal(text)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -24,32 +24,83 @@ describe RE2::Scanner do
|
|
24
24
|
it "returns the next array of matches" do
|
25
25
|
r = RE2::Regexp.new('(\w+)')
|
26
26
|
scanner = r.scan("It is a truth universally acknowledged")
|
27
|
-
scanner.scan.
|
28
|
-
scanner.scan.
|
29
|
-
scanner.scan.
|
30
|
-
scanner.scan.
|
31
|
-
scanner.scan.
|
32
|
-
scanner.scan.
|
33
|
-
scanner.scan.
|
27
|
+
expect(scanner.scan).to eq(["It"])
|
28
|
+
expect(scanner.scan).to eq(["is"])
|
29
|
+
expect(scanner.scan).to eq(["a"])
|
30
|
+
expect(scanner.scan).to eq(["truth"])
|
31
|
+
expect(scanner.scan).to eq(["universally"])
|
32
|
+
expect(scanner.scan).to eq(["acknowledged"])
|
33
|
+
expect(scanner.scan).to be_nil
|
34
34
|
end
|
35
35
|
|
36
36
|
it "returns an empty array if there are no capturing groups" do
|
37
37
|
r = RE2::Regexp.new('\w+')
|
38
38
|
scanner = r.scan("Foo bar")
|
39
|
-
scanner.scan.
|
39
|
+
expect(scanner.scan).to eq([])
|
40
40
|
end
|
41
41
|
|
42
42
|
it "returns nil if there is no match" do
|
43
43
|
r = RE2::Regexp.new('\d+')
|
44
44
|
scanner = r.scan("Foo bar")
|
45
|
-
scanner.scan.
|
45
|
+
expect(scanner.scan).to be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns an empty array if the input is empty" do
|
49
|
+
r = RE2::Regexp.new("")
|
50
|
+
scanner = r.scan("")
|
51
|
+
expect(scanner.scan).to eq([])
|
52
|
+
expect(scanner.scan).to be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns an array of nil with an empty input and capture" do
|
56
|
+
r = RE2::Regexp.new("()")
|
57
|
+
scanner = r.scan("")
|
58
|
+
expect(scanner.scan).to eq([nil])
|
59
|
+
expect(scanner.scan).to be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns an empty array for every match if the pattern is empty" do
|
63
|
+
r = RE2::Regexp.new("")
|
64
|
+
scanner = r.scan("Foo")
|
65
|
+
expect(scanner.scan).to eq([])
|
66
|
+
expect(scanner.scan).to eq([])
|
67
|
+
expect(scanner.scan).to eq([])
|
68
|
+
expect(scanner.scan).to eq([])
|
69
|
+
expect(scanner.scan).to be_nil
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns an array of nil if the pattern is an empty capturing group" do
|
73
|
+
r = RE2::Regexp.new("()")
|
74
|
+
scanner = r.scan("Foo")
|
75
|
+
expect(scanner.scan).to eq([nil])
|
76
|
+
expect(scanner.scan).to eq([nil])
|
77
|
+
expect(scanner.scan).to eq([nil])
|
78
|
+
expect(scanner.scan).to eq([nil])
|
79
|
+
expect(scanner.scan).to be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns array of nils with multiple empty capturing groups" do
|
83
|
+
r = RE2::Regexp.new("()()()")
|
84
|
+
scanner = r.scan("Foo")
|
85
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
86
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
87
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
88
|
+
expect(scanner.scan).to eq([nil, nil, nil])
|
89
|
+
expect(scanner.scan).to be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it "supports empty groups with multibyte characters" do
|
93
|
+
r = RE2::Regexp.new("()€")
|
94
|
+
scanner = r.scan("€")
|
95
|
+
expect(scanner.scan).to eq([nil])
|
96
|
+
expect(scanner.scan).to be_nil
|
46
97
|
end
|
47
98
|
end
|
48
99
|
|
49
100
|
it "is enumerable" do
|
50
101
|
r = RE2::Regexp.new('(\d)')
|
51
102
|
scanner = r.scan("There are 1 some 2 numbers 3")
|
52
|
-
scanner.
|
103
|
+
expect(scanner).to be_a(Enumerable)
|
53
104
|
end
|
54
105
|
|
55
106
|
describe "#each" do
|
@@ -61,7 +112,7 @@ describe RE2::Scanner do
|
|
61
112
|
matches << match
|
62
113
|
end
|
63
114
|
|
64
|
-
matches.
|
115
|
+
expect(matches).to eq([["1"], ["2"], ["3"]])
|
65
116
|
end
|
66
117
|
|
67
118
|
it "returns an enumerator when not given a block" do
|
@@ -70,9 +121,9 @@ describe RE2::Scanner do
|
|
70
121
|
|
71
122
|
# Prior to Ruby 1.9, Enumerator was within Enumerable.
|
72
123
|
if defined?(Enumerator)
|
73
|
-
scanner.each.
|
124
|
+
expect(scanner.each).to be_a(Enumerator)
|
74
125
|
elsif defined?(Enumerable::Enumerator)
|
75
|
-
scanner.each.
|
126
|
+
expect(scanner.each).to be_a(Enumerable::Enumerator)
|
76
127
|
end
|
77
128
|
end
|
78
129
|
end
|
@@ -81,10 +132,67 @@ describe RE2::Scanner do
|
|
81
132
|
it "resets any consumption" do
|
82
133
|
r = RE2::Regexp.new('(\d)')
|
83
134
|
scanner = r.scan("There are 1 some 2 numbers 3")
|
84
|
-
scanner.to_enum.first.
|
85
|
-
scanner.to_enum.first.
|
135
|
+
expect(scanner.to_enum.first).to eq(["1"])
|
136
|
+
expect(scanner.to_enum.first).to eq(["2"])
|
137
|
+
scanner.rewind
|
138
|
+
expect(scanner.to_enum.first).to eq(["1"])
|
139
|
+
end
|
140
|
+
|
141
|
+
it "resets the eof? check" do
|
142
|
+
r = RE2::Regexp.new('(\d)')
|
143
|
+
scanner = r.scan("1")
|
144
|
+
scanner.scan
|
145
|
+
expect(scanner.eof?).to be_truthy
|
86
146
|
scanner.rewind
|
87
|
-
scanner.
|
147
|
+
expect(scanner.eof?).to be_falsey
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#eof?" do
|
152
|
+
it "returns false if the input has not been consumed" do
|
153
|
+
r = RE2::Regexp.new('(\d)')
|
154
|
+
scanner = r.scan("1 2 3")
|
155
|
+
|
156
|
+
expect(scanner.eof?).to be_falsey
|
157
|
+
end
|
158
|
+
|
159
|
+
it "returns true if the input has been consumed" do
|
160
|
+
r = RE2::Regexp.new('(\d)')
|
161
|
+
scanner = r.scan("1")
|
162
|
+
scanner.scan
|
163
|
+
|
164
|
+
expect(scanner.eof?).to be_truthy
|
165
|
+
end
|
166
|
+
|
167
|
+
it "returns false if no match is made" do
|
168
|
+
r = RE2::Regexp.new('(\d)')
|
169
|
+
scanner = r.scan("a")
|
170
|
+
scanner.scan
|
171
|
+
|
172
|
+
expect(scanner.eof?).to be_falsey
|
173
|
+
end
|
174
|
+
|
175
|
+
it "returns false with an empty input that has not been scanned" do
|
176
|
+
r = RE2::Regexp.new("")
|
177
|
+
scanner = r.scan("")
|
178
|
+
|
179
|
+
expect(scanner.eof?).to be_falsey
|
180
|
+
end
|
181
|
+
|
182
|
+
it "returns false with an empty input that has not been matched" do
|
183
|
+
r = RE2::Regexp.new('(\d)')
|
184
|
+
scanner = r.scan("")
|
185
|
+
scanner.scan
|
186
|
+
|
187
|
+
expect(scanner.eof?).to be_falsey
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns true with an empty input that has been matched" do
|
191
|
+
r = RE2::Regexp.new("")
|
192
|
+
scanner = r.scan("")
|
193
|
+
scanner.scan
|
194
|
+
|
195
|
+
expect(scanner.eof?).to be_truthy
|
88
196
|
end
|
89
197
|
end
|
90
198
|
end
|
data/spec/re2/string_spec.rb
CHANGED
@@ -1,57 +1,56 @@
|
|
1
|
-
require "spec_helper"
|
2
1
|
require "re2/string"
|
3
2
|
|
4
3
|
class String
|
5
4
|
include RE2::String
|
6
5
|
end
|
7
6
|
|
8
|
-
describe RE2::String do
|
7
|
+
RSpec.describe RE2::String do
|
9
8
|
describe "#re2_sub" do
|
10
9
|
it "delegates to RE2.Replace to perform replacement" do
|
11
|
-
"My name is Robert Paulson".re2_sub('Robert', 'Crobert').
|
10
|
+
expect("My name is Robert Paulson".re2_sub('Robert', 'Crobert')).to eq("My name is Crobert Paulson")
|
12
11
|
end
|
13
12
|
|
14
13
|
it "doesn't perform an in-place replacement" do
|
15
14
|
string = "My name is Robert Paulson"
|
16
|
-
string.re2_sub('Robert', 'Crobert').
|
15
|
+
expect(string.re2_sub('Robert', 'Crobert')).to_not equal(string)
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
describe "#re2_gsub" do
|
21
20
|
it "delegates to RE2.GlobalReplace to perform replacement" do
|
22
|
-
"My name is Robert Paulson".re2_gsub('a', 'e').
|
21
|
+
expect("My name is Robert Paulson".re2_gsub('a', 'e')).to eq("My neme is Robert Peulson")
|
23
22
|
end
|
24
23
|
|
25
24
|
it "doesn't perform an in-place replacement" do
|
26
25
|
string = "My name is Robert Paulson"
|
27
|
-
string.re2_gsub('a', 'e').
|
26
|
+
expect(string.re2_gsub('a', 'e')).to_not equal(string)
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
30
|
describe "#re2_match" do
|
32
31
|
it "delegates to RE2::Regexp#match to perform matches" do
|
33
32
|
md = "My name is Robert Paulson".re2_match('My name is (\S+) (\S+)')
|
34
|
-
md.
|
35
|
-
md[0].
|
36
|
-
md[1].
|
37
|
-
md[2].
|
33
|
+
expect(md).to be_a(RE2::MatchData)
|
34
|
+
expect(md[0]).to eq("My name is Robert Paulson")
|
35
|
+
expect(md[1]).to eq("Robert")
|
36
|
+
expect(md[2]).to eq("Paulson")
|
38
37
|
end
|
39
38
|
|
40
39
|
it "supports limiting the number of matches" do
|
41
40
|
md = "My name is Robert Paulson".re2_match('My name is (\S+) (\S+)', 0)
|
42
|
-
md.
|
41
|
+
expect(md).to eq(true)
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
46
45
|
describe "#re2_escape" do
|
47
46
|
it "escapes the string for use in regular expressions" do
|
48
|
-
"1.5-2.0?".re2_escape.
|
47
|
+
expect("1.5-2.0?".re2_escape).to eq('1\.5\-2\.0\?')
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
51
|
describe "#re2_quote" do
|
53
52
|
it "escapes the string for use in regular expressions" do
|
54
|
-
"1.5-2.0?".re2_quote.
|
53
|
+
expect("1.5-2.0?".re2_quote).to eq('1\.5\-2\.0\?')
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
data/spec/re2_spec.rb
CHANGED
@@ -1,79 +1,75 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe RE2 do
|
1
|
+
RSpec.describe RE2 do
|
4
2
|
describe "#Replace" do
|
5
3
|
it "only replaces the first occurrence of the pattern" do
|
6
|
-
RE2.Replace("woo", "o", "a").
|
4
|
+
expect(RE2.Replace("woo", "o", "a")).to eq("wao")
|
7
5
|
end
|
8
6
|
|
9
7
|
it "performs replacement based on regular expressions" do
|
10
|
-
RE2.Replace("woo", "o+", "e").
|
8
|
+
expect(RE2.Replace("woo", "o+", "e")).to eq("we")
|
11
9
|
end
|
12
10
|
|
13
11
|
it "supports flags in patterns" do
|
14
|
-
RE2.Replace("Good morning", "(?i)gOOD MORNING", "hi").
|
12
|
+
expect(RE2.Replace("Good morning", "(?i)gOOD MORNING", "hi")).to eq("hi")
|
15
13
|
end
|
16
14
|
|
17
15
|
it "does not perform replacements in-place" do
|
18
16
|
name = "Robert"
|
19
17
|
replacement = RE2.Replace(name, "R", "Cr")
|
20
|
-
|
21
|
-
name.wont_be_same_as(replacement)
|
18
|
+
expect(name).to_not equal(replacement)
|
22
19
|
end
|
23
20
|
|
24
21
|
it "supports passing an RE2::Regexp as the pattern" do
|
25
22
|
re = RE2::Regexp.new('wo{2}')
|
26
|
-
RE2.Replace("woo", re, "miaow").
|
23
|
+
expect(RE2.Replace("woo", re, "miaow")).to eq("miaow")
|
27
24
|
end
|
28
25
|
|
29
26
|
it "respects any passed RE2::Regexp's flags" do
|
30
27
|
re = RE2::Regexp.new('gOOD MORNING', :case_sensitive => false)
|
31
|
-
RE2.Replace("Good morning", re, "hi").
|
28
|
+
expect(RE2.Replace("Good morning", re, "hi")).to eq("hi")
|
32
29
|
end
|
33
30
|
|
34
31
|
if String.method_defined?(:encoding)
|
35
32
|
it "preserves the original string's encoding" do
|
36
33
|
original = "Foo"
|
37
34
|
replacement = RE2.Replace(original, "oo", "ah")
|
38
|
-
original.encoding.
|
35
|
+
expect(original.encoding).to eq(replacement.encoding)
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
43
40
|
describe "#GlobalReplace" do
|
44
41
|
it "replaces every occurrence of a pattern" do
|
45
|
-
RE2.GlobalReplace("woo", "o", "a").
|
42
|
+
expect(RE2.GlobalReplace("woo", "o", "a")).to eq("waa")
|
46
43
|
end
|
47
44
|
|
48
45
|
it "performs replacement based on regular expressions" do
|
49
|
-
RE2.GlobalReplace("woohoo", "o+", "e").
|
46
|
+
expect(RE2.GlobalReplace("woohoo", "o+", "e")).to eq("wehe")
|
50
47
|
end
|
51
48
|
|
52
49
|
it "supports flags in patterns" do
|
53
|
-
RE2.GlobalReplace("Robert", "(?i)r", "w").
|
50
|
+
expect(RE2.GlobalReplace("Robert", "(?i)r", "w")).to eq("wobewt")
|
54
51
|
end
|
55
52
|
|
56
53
|
it "does not perform replacement in-place" do
|
57
54
|
name = "Robert"
|
58
55
|
replacement = RE2.GlobalReplace(name, "(?i)R", "w")
|
59
|
-
|
60
|
-
name.wont_be_same_as(replacement)
|
56
|
+
expect(name).to_not equal(replacement)
|
61
57
|
end
|
62
58
|
|
63
59
|
it "supports passing an RE2::Regexp as the pattern" do
|
64
60
|
re = RE2::Regexp.new('wo{2,}')
|
65
|
-
RE2.GlobalReplace("woowooo", re, "miaow").
|
61
|
+
expect(RE2.GlobalReplace("woowooo", re, "miaow")).to eq("miaowmiaow")
|
66
62
|
end
|
67
63
|
|
68
64
|
it "respects any passed RE2::Regexp's flags" do
|
69
65
|
re = RE2::Regexp.new('gOOD MORNING', :case_sensitive => false)
|
70
|
-
RE2.GlobalReplace("Good morning Good morning", re, "hi").
|
66
|
+
expect(RE2.GlobalReplace("Good morning Good morning", re, "hi")).to eq("hi hi")
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
74
70
|
describe "#QuoteMeta" do
|
75
71
|
it "escapes a string so it can be used as a regular expression" do
|
76
|
-
RE2.QuoteMeta("1.5-2.0?").
|
72
|
+
expect(RE2.QuoteMeta("1.5-2.0?")).to eq('1\.5\-2\.0\?')
|
77
73
|
end
|
78
74
|
end
|
79
75
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
-
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
1
|
require "re2"
|
3
|
-
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.expect_with :rspec do |expectations|
|
5
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
6
|
+
end
|
7
|
+
|
8
|
+
config.mock_with :rspec do |mocks|
|
9
|
+
mocks.verify_partial_doubles = true
|
10
|
+
end
|
11
|
+
|
12
|
+
config.filter_run :focus
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
config.disable_monkey_patching!
|
15
|
+
config.warnings = true
|
16
|
+
config.default_formatter = 'doc' if config.files_to_run.one?
|
17
|
+
config.order = :random
|
18
|
+
Kernel.srand config.seed
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: re2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Mucur
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -25,21 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '3.2'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '3.2'
|
41
41
|
description: Ruby bindings to re2, "an efficient, principled regular expression library".
|
42
|
-
email:
|
42
|
+
email:
|
43
43
|
executables: []
|
44
44
|
extensions:
|
45
45
|
- ext/re2/extconf.rb
|
@@ -60,11 +60,11 @@ files:
|
|
60
60
|
- spec/re2/string_spec.rb
|
61
61
|
- spec/re2_spec.rb
|
62
62
|
- spec/spec_helper.rb
|
63
|
-
homepage:
|
63
|
+
homepage: https://github.com/mudge/re2
|
64
64
|
licenses:
|
65
|
-
- BSD
|
65
|
+
- BSD-3-Clause
|
66
66
|
metadata: {}
|
67
|
-
post_install_message:
|
67
|
+
post_install_message:
|
68
68
|
rdoc_options: []
|
69
69
|
require_paths:
|
70
70
|
- lib
|
@@ -79,9 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
|
-
|
83
|
-
|
84
|
-
signing_key:
|
82
|
+
rubygems_version: 3.1.4
|
83
|
+
signing_key:
|
85
84
|
specification_version: 4
|
86
85
|
summary: Ruby bindings to re2.
|
87
86
|
test_files:
|
@@ -92,4 +91,3 @@ test_files:
|
|
92
91
|
- spec/re2/match_data_spec.rb
|
93
92
|
- spec/re2/string_spec.rb
|
94
93
|
- spec/re2/scanner_spec.rb
|
95
|
-
has_rdoc:
|