re2 2.4.3-arm-linux → 2.5.0-arm-linux
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 +4 -4
- data/README.md +236 -192
- data/ext/re2/extconf.rb +6 -70
- data/ext/re2/re2.cc +450 -263
- data/ext/re2/recipes.rb +8 -0
- data/lib/2.6/re2.so +0 -0
- data/lib/2.7/re2.so +0 -0
- data/lib/3.0/re2.so +0 -0
- data/lib/3.1/re2.so +0 -0
- data/lib/3.2/re2.so +0 -0
- data/lib/re2/regexp.rb +69 -0
- data/lib/re2/scanner.rb +8 -0
- data/lib/re2/string.rb +9 -59
- data/lib/re2/version.rb +9 -1
- data/lib/re2.rb +7 -3
- data/re2.gemspec +1 -0
- data/spec/kernel_spec.rb +2 -2
- data/spec/re2/match_data_spec.rb +64 -25
- data/spec/re2/regexp_spec.rb +492 -113
- data/spec/re2/scanner_spec.rb +3 -8
- data/spec/re2/set_spec.rb +18 -18
- data/spec/re2_spec.rb +4 -4
- metadata +3 -2
data/spec/re2/regexp_spec.rb
CHANGED
@@ -2,11 +2,13 @@ RSpec.describe RE2::Regexp do
|
|
2
2
|
describe "#initialize" do
|
3
3
|
it "returns an instance given only a pattern" do
|
4
4
|
re = RE2::Regexp.new('woo')
|
5
|
+
|
5
6
|
expect(re).to be_a(RE2::Regexp)
|
6
7
|
end
|
7
8
|
|
8
9
|
it "returns an instance given a pattern and options" do
|
9
|
-
re = RE2::Regexp.new('woo', :
|
10
|
+
re = RE2::Regexp.new('woo', case_sensitive: false)
|
11
|
+
|
10
12
|
expect(re).to be_a(RE2::Regexp)
|
11
13
|
end
|
12
14
|
|
@@ -15,7 +17,8 @@ RSpec.describe RE2::Regexp do
|
|
15
17
|
end
|
16
18
|
|
17
19
|
it "allows invalid patterns to be created" do
|
18
|
-
re = RE2::Regexp.new('???', :
|
20
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
21
|
+
|
19
22
|
expect(re).to be_a(RE2::Regexp)
|
20
23
|
end
|
21
24
|
|
@@ -29,11 +32,12 @@ RSpec.describe RE2::Regexp do
|
|
29
32
|
describe ".compile" do
|
30
33
|
it "returns an instance given only a pattern" do
|
31
34
|
re = RE2::Regexp.compile('woo')
|
35
|
+
|
32
36
|
expect(re).to be_a(RE2::Regexp)
|
33
37
|
end
|
34
38
|
|
35
39
|
it "returns an instance given a pattern and options" do
|
36
|
-
re = RE2::Regexp.compile('woo', :
|
40
|
+
re = RE2::Regexp.compile('woo', case_sensitive: false)
|
37
41
|
expect(re).to be_a(RE2::Regexp)
|
38
42
|
end
|
39
43
|
|
@@ -42,7 +46,8 @@ RSpec.describe RE2::Regexp do
|
|
42
46
|
end
|
43
47
|
|
44
48
|
it "allows invalid patterns to be created" do
|
45
|
-
re = RE2::Regexp.compile('???', :
|
49
|
+
re = RE2::Regexp.compile('???', log_errors: false)
|
50
|
+
|
46
51
|
expect(re).to be_a(RE2::Regexp)
|
47
52
|
end
|
48
53
|
|
@@ -60,34 +65,38 @@ RSpec.describe RE2::Regexp do
|
|
60
65
|
end
|
61
66
|
|
62
67
|
it "is populated with default options when nothing has been set" do
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
68
|
+
expect(RE2::Regexp.new('woo').options).to include(
|
69
|
+
utf8: true,
|
70
|
+
posix_syntax: false,
|
71
|
+
longest_match: false,
|
72
|
+
log_errors: true,
|
73
|
+
literal: false,
|
74
|
+
never_nl: false,
|
75
|
+
case_sensitive: true,
|
76
|
+
perl_classes: false,
|
77
|
+
word_boundary: false,
|
78
|
+
one_line: false
|
79
|
+
)
|
74
80
|
end
|
75
81
|
|
76
82
|
it "is populated with overridden options when specified" do
|
77
|
-
options = RE2::Regexp.new('woo', :
|
78
|
-
|
83
|
+
options = RE2::Regexp.new('woo', case_sensitive: false).options
|
84
|
+
|
85
|
+
expect(options).to include(case_sensitive: false)
|
79
86
|
end
|
80
87
|
end
|
81
88
|
|
82
89
|
describe "#error" do
|
83
90
|
it "returns nil if there is no error" do
|
84
91
|
error = RE2::Regexp.new('woo').error
|
92
|
+
|
85
93
|
expect(error).to be_nil
|
86
94
|
end
|
87
95
|
|
88
|
-
# Use log_errors
|
96
|
+
# Use log_errors: false to suppress RE2's logging to STDERR.
|
89
97
|
it "contains the error string if there is an error" do
|
90
|
-
error = RE2::Regexp.new('wo(o', :
|
98
|
+
error = RE2::Regexp.new('wo(o', log_errors: false).error
|
99
|
+
|
91
100
|
expect(error).to eq("missing ): wo(o")
|
92
101
|
end
|
93
102
|
end
|
@@ -95,11 +104,13 @@ RSpec.describe RE2::Regexp do
|
|
95
104
|
describe "#error_arg" do
|
96
105
|
it "returns nil if there is no error" do
|
97
106
|
error_arg = RE2::Regexp.new('woo').error_arg
|
107
|
+
|
98
108
|
expect(error_arg).to be_nil
|
99
109
|
end
|
100
110
|
|
101
|
-
it "returns the offending portion of the
|
102
|
-
error_arg = RE2::Regexp.new('wo(o', :
|
111
|
+
it "returns the offending portion of the pattern if there is an error" do
|
112
|
+
error_arg = RE2::Regexp.new('wo(o', log_errors: false).error_arg
|
113
|
+
|
103
114
|
expect(error_arg).to eq("wo(o")
|
104
115
|
end
|
105
116
|
end
|
@@ -112,7 +123,8 @@ RSpec.describe RE2::Regexp do
|
|
112
123
|
end
|
113
124
|
|
114
125
|
it "returns -1 for an invalid pattern" do
|
115
|
-
program_size = RE2::Regexp.new('???', :
|
126
|
+
program_size = RE2::Regexp.new('???', log_errors: false).program_size
|
127
|
+
|
116
128
|
expect(program_size).to eq(-1)
|
117
129
|
end
|
118
130
|
end
|
@@ -120,18 +132,27 @@ RSpec.describe RE2::Regexp do
|
|
120
132
|
describe "#to_str" do
|
121
133
|
it "returns the original pattern" do
|
122
134
|
string = RE2::Regexp.new('w(o)(o)').to_str
|
135
|
+
|
123
136
|
expect(string).to eq("w(o)(o)")
|
124
137
|
end
|
138
|
+
|
139
|
+
it "returns the pattern even if invalid" do
|
140
|
+
string = RE2::Regexp.new('???', log_errors: false).to_str
|
141
|
+
|
142
|
+
expect(string).to eq("???")
|
143
|
+
end
|
125
144
|
end
|
126
145
|
|
127
146
|
describe "#pattern" do
|
128
147
|
it "returns the original pattern" do
|
129
148
|
pattern = RE2::Regexp.new('w(o)(o)').pattern
|
149
|
+
|
130
150
|
expect(pattern).to eq("w(o)(o)")
|
131
151
|
end
|
132
152
|
|
133
153
|
it "returns the pattern even if invalid" do
|
134
|
-
pattern = RE2::Regexp.new('???', :
|
154
|
+
pattern = RE2::Regexp.new('???', log_errors: false).pattern
|
155
|
+
|
135
156
|
expect(pattern).to eq("???")
|
136
157
|
end
|
137
158
|
end
|
@@ -139,8 +160,15 @@ RSpec.describe RE2::Regexp do
|
|
139
160
|
describe "#inspect" do
|
140
161
|
it "shows the class name and original pattern" do
|
141
162
|
string = RE2::Regexp.new('w(o)(o)').inspect
|
163
|
+
|
142
164
|
expect(string).to eq("#<RE2::Regexp /w(o)(o)/>")
|
143
165
|
end
|
166
|
+
|
167
|
+
it "respects the pattern's original encoding" do
|
168
|
+
string = RE2::Regexp.new('w(o)(o)', utf8: false).inspect
|
169
|
+
|
170
|
+
expect(string.encoding).to eq(Encoding::ISO_8859_1)
|
171
|
+
end
|
144
172
|
end
|
145
173
|
|
146
174
|
describe "#utf8?" do
|
@@ -149,7 +177,8 @@ RSpec.describe RE2::Regexp do
|
|
149
177
|
end
|
150
178
|
|
151
179
|
it "can be overridden on initialization" do
|
152
|
-
re = RE2::Regexp.new('woo', :
|
180
|
+
re = RE2::Regexp.new('woo', utf8: false)
|
181
|
+
|
153
182
|
expect(re).to_not be_utf8
|
154
183
|
end
|
155
184
|
end
|
@@ -160,7 +189,8 @@ RSpec.describe RE2::Regexp do
|
|
160
189
|
end
|
161
190
|
|
162
191
|
it "can be overridden on initialization" do
|
163
|
-
re = RE2::Regexp.new('woo', :
|
192
|
+
re = RE2::Regexp.new('woo', posix_syntax: true)
|
193
|
+
|
164
194
|
expect(re).to be_posix_syntax
|
165
195
|
end
|
166
196
|
end
|
@@ -171,7 +201,8 @@ RSpec.describe RE2::Regexp do
|
|
171
201
|
end
|
172
202
|
|
173
203
|
it "can be overridden on initialization" do
|
174
|
-
re = RE2::Regexp.new('woo', :
|
204
|
+
re = RE2::Regexp.new('woo', literal: true)
|
205
|
+
|
175
206
|
expect(re).to be_literal
|
176
207
|
end
|
177
208
|
end
|
@@ -182,7 +213,8 @@ RSpec.describe RE2::Regexp do
|
|
182
213
|
end
|
183
214
|
|
184
215
|
it "can be overridden on initialization" do
|
185
|
-
re = RE2::Regexp.new('woo', :
|
216
|
+
re = RE2::Regexp.new('woo', never_nl: true)
|
217
|
+
|
186
218
|
expect(re).to be_never_nl
|
187
219
|
end
|
188
220
|
end
|
@@ -193,7 +225,7 @@ RSpec.describe RE2::Regexp do
|
|
193
225
|
end
|
194
226
|
|
195
227
|
it "can be overridden on initialization" do
|
196
|
-
re = RE2::Regexp.new('woo', :
|
228
|
+
re = RE2::Regexp.new('woo', case_sensitive: false)
|
197
229
|
expect(re).to_not be_case_sensitive
|
198
230
|
end
|
199
231
|
end
|
@@ -204,7 +236,8 @@ RSpec.describe RE2::Regexp do
|
|
204
236
|
end
|
205
237
|
|
206
238
|
it "can be overridden on initialization" do
|
207
|
-
re = RE2::Regexp.new('woo', :
|
239
|
+
re = RE2::Regexp.new('woo', case_sensitive: false)
|
240
|
+
|
208
241
|
expect(re).to be_case_insensitive
|
209
242
|
end
|
210
243
|
end
|
@@ -215,7 +248,8 @@ RSpec.describe RE2::Regexp do
|
|
215
248
|
end
|
216
249
|
|
217
250
|
it "can be overridden on initialization" do
|
218
|
-
re = RE2::Regexp.new('woo', :
|
251
|
+
re = RE2::Regexp.new('woo', case_sensitive: false)
|
252
|
+
|
219
253
|
expect(re).to be_casefold
|
220
254
|
end
|
221
255
|
end
|
@@ -226,7 +260,8 @@ RSpec.describe RE2::Regexp do
|
|
226
260
|
end
|
227
261
|
|
228
262
|
it "can be overridden on initialization" do
|
229
|
-
re = RE2::Regexp.new('woo', :
|
263
|
+
re = RE2::Regexp.new('woo', longest_match: true)
|
264
|
+
|
230
265
|
expect(re).to be_longest_match
|
231
266
|
end
|
232
267
|
end
|
@@ -237,7 +272,8 @@ RSpec.describe RE2::Regexp do
|
|
237
272
|
end
|
238
273
|
|
239
274
|
it "can be overridden on initialization" do
|
240
|
-
re = RE2::Regexp.new('woo', :
|
275
|
+
re = RE2::Regexp.new('woo', log_errors: false)
|
276
|
+
|
241
277
|
expect(re).to_not be_log_errors
|
242
278
|
end
|
243
279
|
end
|
@@ -248,7 +284,8 @@ RSpec.describe RE2::Regexp do
|
|
248
284
|
end
|
249
285
|
|
250
286
|
it "can be overridden on initialization" do
|
251
|
-
re = RE2::Regexp.new('woo', :
|
287
|
+
re = RE2::Regexp.new('woo', perl_classes: true)
|
288
|
+
|
252
289
|
expect(re).to be_perl_classes
|
253
290
|
end
|
254
291
|
end
|
@@ -259,7 +296,8 @@ RSpec.describe RE2::Regexp do
|
|
259
296
|
end
|
260
297
|
|
261
298
|
it "can be overridden on initialization" do
|
262
|
-
re = RE2::Regexp.new('woo', :
|
299
|
+
re = RE2::Regexp.new('woo', word_boundary: true)
|
300
|
+
|
263
301
|
expect(re).to be_word_boundary
|
264
302
|
end
|
265
303
|
end
|
@@ -270,7 +308,8 @@ RSpec.describe RE2::Regexp do
|
|
270
308
|
end
|
271
309
|
|
272
310
|
it "can be overridden on initialization" do
|
273
|
-
re = RE2::Regexp.new('woo', :
|
311
|
+
re = RE2::Regexp.new('woo', one_line: true)
|
312
|
+
|
274
313
|
expect(re).to be_one_line
|
275
314
|
end
|
276
315
|
end
|
@@ -281,144 +320,372 @@ RSpec.describe RE2::Regexp do
|
|
281
320
|
end
|
282
321
|
|
283
322
|
it "can be overridden on initialization" do
|
284
|
-
re = RE2::Regexp.new('woo', :
|
323
|
+
re = RE2::Regexp.new('woo', max_mem: 1024)
|
324
|
+
|
285
325
|
expect(re.max_mem).to eq(1024)
|
286
326
|
end
|
287
327
|
end
|
288
328
|
|
289
329
|
describe "#match" do
|
290
|
-
|
330
|
+
it "returns match data given only text if the pattern has capturing groups" do
|
331
|
+
re = RE2::Regexp.new('My name is (\w+) (\w+)')
|
291
332
|
|
292
|
-
|
293
|
-
md = re.match("My name is Robert Paulson")
|
294
|
-
expect(md).to be_a(RE2::MatchData)
|
333
|
+
expect(re.match("My name is Alice Bloggs")).to be_a(RE2::MatchData)
|
295
334
|
end
|
296
335
|
|
297
|
-
it "returns
|
298
|
-
|
336
|
+
it "returns only true or false given only text if the pattern has no capturing groups" do
|
337
|
+
re = RE2::Regexp.new('My name is \w+ \w+')
|
338
|
+
|
339
|
+
expect(re.match("My name is Alice Bloggs")).to eq(true)
|
299
340
|
end
|
300
341
|
|
301
|
-
it "returns
|
302
|
-
|
303
|
-
|
342
|
+
it "returns nil if the text does not match the pattern" do
|
343
|
+
re = RE2::Regexp.new('My name is (\w+) (\w+)')
|
344
|
+
|
345
|
+
expect(re.match("My age is 99")).to be_nil
|
304
346
|
end
|
305
347
|
|
306
|
-
it "
|
307
|
-
re = RE2::Regexp.new('My name is')
|
348
|
+
it "accepts text that can be coerced to a string" do
|
349
|
+
re = RE2::Regexp.new('My name is (\w+) (\w+)')
|
308
350
|
|
309
|
-
expect(re.match(
|
351
|
+
expect(re.match(StringLike.new("My name is Alice Bloggs"))).to be_a(RE2::MatchData)
|
310
352
|
end
|
311
353
|
|
312
|
-
it "raises an exception when given
|
354
|
+
it "raises an exception when given text that cannot be coerced to a string" do
|
355
|
+
re = RE2::Regexp.new('My name is (\w+) (\w+)')
|
356
|
+
|
313
357
|
expect { re.match(nil) }.to raise_error(TypeError)
|
314
358
|
end
|
315
359
|
|
316
|
-
it "
|
317
|
-
|
360
|
+
it "returns nil with an invalid pattern" do
|
361
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
362
|
+
|
363
|
+
expect(re.match("My name is Alice Bloggs")).to be_nil
|
364
|
+
end
|
365
|
+
|
366
|
+
it "returns nil with an invalid pattern and options" do
|
367
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
368
|
+
|
369
|
+
expect(re.match('foo bar', startpos: 1)).to be_nil
|
318
370
|
end
|
319
371
|
|
320
|
-
it "
|
321
|
-
|
372
|
+
it "accepts an offset at which to start matching", :aggregate_failures do
|
373
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
374
|
+
md = re.match("one two three", startpos: 4)
|
375
|
+
|
376
|
+
expect(md[1]).to eq("two")
|
377
|
+
expect(md[2]).to eq("three")
|
322
378
|
end
|
323
379
|
|
324
|
-
it "returns nil
|
325
|
-
|
326
|
-
|
380
|
+
it "returns nil if using a starting offset past the end of the text" do
|
381
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
382
|
+
|
383
|
+
re = RE2::Regexp.new('(\w+) (\w+)', log_errors: false)
|
384
|
+
|
385
|
+
expect(re.match("one two three", startpos: 20, endpos: 21)).to be_nil
|
327
386
|
end
|
328
387
|
|
329
|
-
|
330
|
-
|
388
|
+
it "raises an exception when given a negative starting offset" do
|
389
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
331
390
|
|
332
|
-
|
333
|
-
|
334
|
-
|
391
|
+
expect { re.match("one two three", startpos: -1) }.to raise_error(ArgumentError, "startpos should be >= 0")
|
392
|
+
end
|
393
|
+
|
394
|
+
it "raises an exception when given a starting offset past the default ending offset" do
|
395
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
396
|
+
|
397
|
+
expect { re.match("one two three", startpos: 30) }.to raise_error(ArgumentError, "startpos should be <= endpos")
|
398
|
+
end
|
335
399
|
|
336
|
-
|
337
|
-
|
338
|
-
end
|
400
|
+
it "accepts an offset at which to end matching", :aggregate_failures do
|
401
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
339
402
|
|
340
|
-
|
341
|
-
|
342
|
-
end
|
403
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
404
|
+
md = re.match("one two three", endpos: 6)
|
343
405
|
|
344
|
-
|
345
|
-
|
346
|
-
end
|
406
|
+
expect(md[1]).to eq("one")
|
407
|
+
expect(md[2]).to eq("tw")
|
347
408
|
end
|
348
409
|
|
349
|
-
|
350
|
-
|
410
|
+
it "returns nil if using a ending offset at the start of the text" do
|
411
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
412
|
+
|
413
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
414
|
+
|
415
|
+
expect(re.match("one two three", endpos: 0)).to be_nil
|
416
|
+
end
|
351
417
|
|
352
|
-
|
353
|
-
|
354
|
-
end
|
418
|
+
it "raises an exception when given a negative ending offset" do
|
419
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
355
420
|
|
356
|
-
|
357
|
-
|
358
|
-
|
421
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
422
|
+
|
423
|
+
expect { re.match("one two three", endpos: -1) }.to raise_error(ArgumentError, "endpos should be >= 0")
|
424
|
+
end
|
425
|
+
|
426
|
+
it "raises an exception when given an ending offset before the starting offset" do
|
427
|
+
skip "Underlying RE2::Match does not have endpos argument" unless RE2::Regexp.match_has_endpos_argument?
|
428
|
+
|
429
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
430
|
+
|
431
|
+
expect { re.match("one two three", startpos: 3, endpos: 0) }.to raise_error(ArgumentError, "startpos should be <= endpos")
|
432
|
+
end
|
433
|
+
|
434
|
+
it "raises an error if given an ending offset and RE2 does not support it" do
|
435
|
+
skip "Underlying RE2::Match has endpos argument" if RE2::Regexp.match_has_endpos_argument?
|
436
|
+
|
437
|
+
re = RE2::Regexp.new('(\w+) (\w+)')
|
438
|
+
|
439
|
+
expect { re.match("one two three", endpos: 3) }.to raise_error(RE2::Regexp::UnsupportedError)
|
440
|
+
end
|
441
|
+
|
442
|
+
it "does not anchor matches by default when extracting submatches" do
|
443
|
+
re = RE2::Regexp.new('(two)')
|
444
|
+
|
445
|
+
expect(re.match("one two three")).to be_a(RE2::MatchData)
|
446
|
+
end
|
447
|
+
|
448
|
+
it "does not anchor matches by default without extracting submatches" do
|
449
|
+
re = RE2::Regexp.new('(two)')
|
450
|
+
|
451
|
+
expect(re.match("one two three", submatches: 0)).to eq(true)
|
452
|
+
end
|
453
|
+
|
454
|
+
it "can explicitly match without anchoring when extracting submatches" do
|
455
|
+
re = RE2::Regexp.new('(two)')
|
456
|
+
|
457
|
+
expect(re.match("one two three", anchor: :unanchored)).to be_a(RE2::MatchData)
|
458
|
+
end
|
459
|
+
|
460
|
+
it "can explicitly match with neither anchoring nor extracting submatches" do
|
461
|
+
re = RE2::Regexp.new('(two)')
|
462
|
+
|
463
|
+
expect(re.match("one two three", anchor: :unanchored, submatches: 0)).to eq(true)
|
464
|
+
end
|
465
|
+
|
466
|
+
it "can anchor matches at the start when extracting submatches", :aggregate_failures do
|
467
|
+
re = RE2::Regexp.new('(two)')
|
468
|
+
|
469
|
+
expect(re.match("two three", anchor: :anchor_start)).to be_a(RE2::MatchData)
|
470
|
+
expect(re.match("one two three", anchor: :anchor_start)).to be_nil
|
471
|
+
end
|
472
|
+
|
473
|
+
it "can anchor matches at the start without extracting submatches", :aggregate_failures do
|
474
|
+
re = RE2::Regexp.new('(two)')
|
475
|
+
|
476
|
+
expect(re.match("two three", anchor: :anchor_start, submatches: 0)).to eq(true)
|
477
|
+
expect(re.match("one two three", anchor: :anchor_start, submatches: 0)).to eq(false)
|
478
|
+
end
|
479
|
+
|
480
|
+
it "can anchor matches at both ends when extracting submatches", :aggregate_failures do
|
481
|
+
re = RE2::Regexp.new('(two)')
|
482
|
+
|
483
|
+
expect(re.match("two three", anchor: :anchor_both)).to be_nil
|
484
|
+
expect(re.match("two", anchor: :anchor_both)).to be_a(RE2::MatchData)
|
485
|
+
end
|
486
|
+
|
487
|
+
it "does not anchor matches when given a nil anchor" do
|
488
|
+
re = RE2::Regexp.new('(two)')
|
489
|
+
|
490
|
+
expect(re.match("one two three", anchor: nil)).to be_a(RE2::MatchData)
|
491
|
+
end
|
492
|
+
|
493
|
+
it "raises an exception when given an invalid anchor" do
|
494
|
+
re = RE2::Regexp.new('(two)')
|
495
|
+
|
496
|
+
expect { re.match("one two three", anchor: :invalid) }.to raise_error(ArgumentError, "anchor should be one of: :unanchored, :anchor_start, :anchor_both")
|
497
|
+
end
|
498
|
+
|
499
|
+
it "raises an exception when given a non-symbol anchor" do
|
500
|
+
re = RE2::Regexp.new('(two)')
|
501
|
+
|
502
|
+
expect { re.match("one two three", anchor: 0) }.to raise_error(TypeError)
|
503
|
+
end
|
504
|
+
|
505
|
+
it "extracts all submatches by default", :aggregate_failures do
|
506
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
507
|
+
md = re.match("one two three")
|
508
|
+
|
509
|
+
expect(md[1]).to eq("one")
|
510
|
+
expect(md[2]).to eq("two")
|
511
|
+
expect(md[3]).to eq("three")
|
512
|
+
end
|
513
|
+
|
514
|
+
it "extracts a specific number of submatches", :aggregate_failures do
|
515
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
516
|
+
md = re.match("one two three", submatches: 2)
|
517
|
+
|
518
|
+
expect(md[1]).to eq("one")
|
519
|
+
expect(md[2]).to eq("two")
|
520
|
+
expect(md[3]).to be_nil
|
521
|
+
end
|
522
|
+
|
523
|
+
it "pads submatches with nil when requesting more than the number of capturing groups" do
|
524
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
525
|
+
md = re.match("one two three", submatches: 5)
|
526
|
+
|
527
|
+
expect(md.to_a).to eq(["one two three", "one", "two", "three", nil, nil])
|
528
|
+
end
|
529
|
+
|
530
|
+
it "raises an exception when given a negative number of submatches" do
|
531
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
532
|
+
|
533
|
+
expect { re.match("one two three", submatches: -1) }.to raise_error(ArgumentError, "number of matches should be >= 0")
|
534
|
+
end
|
535
|
+
|
536
|
+
it "raises an exception when given a non-numeric number of submatches" do
|
537
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
538
|
+
|
539
|
+
expect { re.match("one two three", submatches: :invalid) }.to raise_error(TypeError)
|
540
|
+
end
|
359
541
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
end
|
542
|
+
it "defaults to extracting all submatches when given nil", :aggregate_failures do
|
543
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
544
|
+
md = re.match("one two three", submatches: nil)
|
364
545
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
546
|
+
expect(md[1]).to eq("one")
|
547
|
+
expect(md[2]).to eq("two")
|
548
|
+
expect(md[3]).to eq("three")
|
549
|
+
end
|
550
|
+
|
551
|
+
it "accepts passing the number of submatches instead of options for backward compatibility", :aggregate_failures do
|
552
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
553
|
+
md = re.match("one two three", 2)
|
554
|
+
|
555
|
+
expect(md[1]).to eq("one")
|
556
|
+
expect(md[2]).to eq("two")
|
557
|
+
expect(md[3]).to be_nil
|
558
|
+
end
|
559
|
+
|
560
|
+
it "raises an exception when given invalid options" do
|
561
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
562
|
+
|
563
|
+
expect { re.match("one two three", :invalid) }.to raise_error(TypeError)
|
564
|
+
end
|
565
|
+
|
566
|
+
it "accepts anything that can be coerced to a hash as options", :aggregate_failures do
|
567
|
+
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
568
|
+
|
569
|
+
expect(re.match("one two three", nil)).to be_a(RE2::MatchData)
|
371
570
|
end
|
372
571
|
end
|
373
572
|
|
374
573
|
describe "#match?" do
|
375
|
-
it "returns only true or false if
|
574
|
+
it "returns only true or false even if there are capturing groups", :aggregate_failures do
|
376
575
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
377
|
-
|
576
|
+
|
577
|
+
expect(re.match?("My name is Alice Bloggs")).to eq(true)
|
378
578
|
expect(re.match?("My age is 99")).to eq(false)
|
379
579
|
end
|
380
580
|
|
381
581
|
it "returns false if the pattern is invalid" do
|
382
|
-
re = RE2::Regexp.new('???', :
|
383
|
-
|
582
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
583
|
+
|
584
|
+
expect(re.match?("My name is Alice Bloggs")).to eq(false)
|
585
|
+
end
|
586
|
+
|
587
|
+
it "raises an exception if text cannot be coerced to a string" do
|
588
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
589
|
+
|
590
|
+
expect { re.match?(0) }.to raise_error(TypeError)
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
describe "#partial_match?" do
|
595
|
+
it "returns only true or false even if there are capturing groups", :aggregate_failures do
|
596
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
597
|
+
|
598
|
+
expect(re.partial_match?("My name is Alice Bloggs")).to eq(true)
|
599
|
+
expect(re.partial_match?("My age is 99")).to eq(false)
|
600
|
+
end
|
601
|
+
|
602
|
+
it "returns false if the pattern is invalid" do
|
603
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
604
|
+
|
605
|
+
expect(re.partial_match?("My name is Alice Bloggs")).to eq(false)
|
606
|
+
end
|
607
|
+
|
608
|
+
it "raises an exception if text cannot be coerced to a string" do
|
609
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
610
|
+
|
611
|
+
expect { re.partial_match?(0) }.to raise_error(TypeError)
|
384
612
|
end
|
385
613
|
end
|
386
614
|
|
387
615
|
describe "#=~" do
|
388
|
-
it "returns only true or false if
|
616
|
+
it "returns only true or false even if there are capturing groups", :aggregate_failures do
|
389
617
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
390
|
-
|
618
|
+
|
619
|
+
expect(re =~ "My name is Alice Bloggs").to eq(true)
|
391
620
|
expect(re =~ "My age is 99").to eq(false)
|
392
621
|
end
|
393
|
-
end
|
394
622
|
|
395
|
-
|
396
|
-
|
623
|
+
it "returns false if the pattern is invalid" do
|
624
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
625
|
+
|
626
|
+
expect(re =~ "My name is Alice Bloggs").to eq(false)
|
627
|
+
end
|
628
|
+
|
629
|
+
it "raises an exception if text cannot be coerced to a string" do
|
397
630
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
398
|
-
|
399
|
-
expect
|
631
|
+
|
632
|
+
expect { re =~ 0 }.to raise_error(TypeError)
|
400
633
|
end
|
401
634
|
end
|
402
635
|
|
403
636
|
describe "#===" do
|
404
|
-
it "returns only true or false if
|
637
|
+
it "returns only true or false even if there are capturing groups", :aggregate_failures do
|
405
638
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
406
|
-
|
639
|
+
|
640
|
+
expect(re === "My name is Alice Bloggs").to eq(true)
|
407
641
|
expect(re === "My age is 99").to eq(false)
|
408
642
|
end
|
643
|
+
|
644
|
+
it "returns false if the pattern is invalid" do
|
645
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
646
|
+
|
647
|
+
expect(re === "My name is Alice Bloggs").to eq(false)
|
648
|
+
end
|
649
|
+
|
650
|
+
it "raises an exception if text cannot be coerced to a string" do
|
651
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
652
|
+
|
653
|
+
expect { re === 0 }.to raise_error(TypeError)
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
describe "#full_match?" do
|
658
|
+
it "returns only true or false even if there are capturing groups", :aggregate_failures do
|
659
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
660
|
+
|
661
|
+
expect(re.full_match?("My name is Alice Bloggs")).to eq(true)
|
662
|
+
expect(re.full_match?("My name is Alice Bloggs and I am 99")).to eq(false)
|
663
|
+
end
|
664
|
+
|
665
|
+
it "returns false if the pattern is invalid" do
|
666
|
+
re = RE2::Regexp.new('???', log_errors: false)
|
667
|
+
|
668
|
+
expect(re.full_match?("My name is Alice Bloggs")).to eq(false)
|
669
|
+
end
|
670
|
+
|
671
|
+
it "raises an exception if text cannot be coerced to a string" do
|
672
|
+
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
673
|
+
|
674
|
+
expect { re.full_match?(0) }.to raise_error(TypeError)
|
675
|
+
end
|
409
676
|
end
|
410
677
|
|
411
678
|
describe "#ok?" do
|
412
|
-
it "returns true for valid
|
679
|
+
it "returns true for valid patterns", :aggregate_failures do
|
413
680
|
expect(RE2::Regexp.new('woo')).to be_ok
|
414
681
|
expect(RE2::Regexp.new('wo(o)')).to be_ok
|
415
682
|
expect(RE2::Regexp.new('((\d)\w+){3,}')).to be_ok
|
416
683
|
end
|
417
684
|
|
418
|
-
it "returns false for invalid
|
419
|
-
expect(RE2::Regexp.new('wo(o', :
|
420
|
-
expect(RE2::Regexp.new('wo[o', :
|
421
|
-
expect(RE2::Regexp.new('*', :
|
685
|
+
it "returns false for invalid patterns", :aggregate_failures do
|
686
|
+
expect(RE2::Regexp.new('wo(o', log_errors: false)).to_not be_ok
|
687
|
+
expect(RE2::Regexp.new('wo[o', log_errors: false)).to_not be_ok
|
688
|
+
expect(RE2::Regexp.new('*', log_errors: false)).to_not be_ok
|
422
689
|
end
|
423
690
|
end
|
424
691
|
|
@@ -435,14 +702,14 @@ RSpec.describe RE2::Regexp do
|
|
435
702
|
end
|
436
703
|
|
437
704
|
describe "#number_of_capturing_groups" do
|
438
|
-
it "returns the number of groups in a
|
705
|
+
it "returns the number of groups in a pattern", :aggregate_failures do
|
439
706
|
expect(RE2::Regexp.new('(a)(b)(c)').number_of_capturing_groups).to eq(3)
|
440
707
|
expect(RE2::Regexp.new('abc').number_of_capturing_groups).to eq(0)
|
441
708
|
expect(RE2::Regexp.new('a((b)c)').number_of_capturing_groups).to eq(2)
|
442
709
|
end
|
443
710
|
|
444
|
-
it "returns -1 for an invalid
|
445
|
-
expect(RE2::Regexp.new('???', :
|
711
|
+
it "returns -1 for an invalid pattern" do
|
712
|
+
expect(RE2::Regexp.new('???', log_errors: false).number_of_capturing_groups).to eq(-1)
|
446
713
|
end
|
447
714
|
end
|
448
715
|
|
@@ -453,17 +720,18 @@ RSpec.describe RE2::Regexp do
|
|
453
720
|
|
454
721
|
it "maps names to indices with only one group" do
|
455
722
|
groups = RE2::Regexp.new('(?P<bob>a)').named_capturing_groups
|
456
|
-
|
723
|
+
|
724
|
+
expect(groups).to eq("bob" => 1)
|
457
725
|
end
|
458
726
|
|
459
727
|
it "maps names to indices with several groups" do
|
460
728
|
groups = RE2::Regexp.new('(?P<bob>a)(o)(?P<rob>e)').named_capturing_groups
|
461
|
-
|
462
|
-
expect(groups
|
729
|
+
|
730
|
+
expect(groups).to eq("bob" => 1, "rob" => 3)
|
463
731
|
end
|
464
732
|
|
465
733
|
it "returns an empty hash for an invalid regexp" do
|
466
|
-
expect(RE2::Regexp.new('???', :
|
734
|
+
expect(RE2::Regexp.new('???', log_errors: false).named_capturing_groups).to be_empty
|
467
735
|
end
|
468
736
|
end
|
469
737
|
|
@@ -475,4 +743,115 @@ RSpec.describe RE2::Regexp do
|
|
475
743
|
expect(scanner).to be_a(RE2::Scanner)
|
476
744
|
end
|
477
745
|
end
|
746
|
+
|
747
|
+
describe "#partial_match" do
|
748
|
+
it "matches the pattern anywhere within the given text" do
|
749
|
+
r = RE2::Regexp.new('f(o+)')
|
750
|
+
|
751
|
+
expect(r.partial_match("foo bar")).to be_a(RE2::MatchData)
|
752
|
+
end
|
753
|
+
|
754
|
+
it "returns true or false if there are no capturing groups" do
|
755
|
+
r = RE2::Regexp.new('fo+')
|
756
|
+
|
757
|
+
expect(r.partial_match("foo bar")).to eq(true)
|
758
|
+
end
|
759
|
+
|
760
|
+
it "can set the number of submatches to extract", :aggregate_failures do
|
761
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
762
|
+
m = r.partial_match("fooaa bar", submatches: 1)
|
763
|
+
|
764
|
+
expect(m[1]).to eq("oo")
|
765
|
+
expect(m[2]).to be_nil
|
766
|
+
|
767
|
+
m = r.partial_match("fooaa bar", submatches: 2)
|
768
|
+
|
769
|
+
expect(m[1]).to eq("oo")
|
770
|
+
expect(m[2]).to eq("aa")
|
771
|
+
end
|
772
|
+
|
773
|
+
it "raises an error if given non-hash options" do
|
774
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
775
|
+
|
776
|
+
expect { r.partial_match("fooaa bar", "not a hash") }.to raise_error(TypeError)
|
777
|
+
end
|
778
|
+
|
779
|
+
it "accepts options that can be coerced to a hash", :aggregate_failures do
|
780
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
781
|
+
|
782
|
+
m = r.partial_match("fooaa bar", nil)
|
783
|
+
expect(m[1]).to eq('oo')
|
784
|
+
|
785
|
+
m = r.partial_match("fooaa bar", [])
|
786
|
+
expect(m[1]).to eq('oo')
|
787
|
+
end
|
788
|
+
|
789
|
+
it "accepts anything that can be coerced to a string" do
|
790
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
791
|
+
|
792
|
+
expect(r.partial_match(StringLike.new("fooaa bar"))).to be_a(RE2::MatchData)
|
793
|
+
end
|
794
|
+
|
795
|
+
it "does not allow the anchor to be overridden" do
|
796
|
+
r = RE2::Regexp.new('(\d+)')
|
797
|
+
|
798
|
+
expect(r.partial_match('ruby:1234', anchor: :anchor_both)).to be_a(RE2::MatchData)
|
799
|
+
end
|
800
|
+
end
|
801
|
+
|
802
|
+
describe "#full_match" do
|
803
|
+
it "only matches the pattern if all of the given text matches", :aggregate_failures do
|
804
|
+
r = RE2::Regexp.new('f(o+)')
|
805
|
+
|
806
|
+
expect(r.full_match("foo")).to be_a(RE2::MatchData)
|
807
|
+
expect(r.full_match("foo bar")).to be_nil
|
808
|
+
end
|
809
|
+
|
810
|
+
it "returns true or false if there are no capturing groups" do
|
811
|
+
r = RE2::Regexp.new('fo+')
|
812
|
+
|
813
|
+
expect(r.full_match("foo")).to eq(true)
|
814
|
+
end
|
815
|
+
|
816
|
+
it "can set the number of submatches to extract", :aggregate_failures do
|
817
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
818
|
+
m = r.full_match("fooaa", submatches: 1)
|
819
|
+
|
820
|
+
expect(m[1]).to eq("oo")
|
821
|
+
expect(m[2]).to be_nil
|
822
|
+
|
823
|
+
m = r.full_match("fooaa", submatches: 2)
|
824
|
+
|
825
|
+
expect(m[1]).to eq("oo")
|
826
|
+
expect(m[2]).to eq("aa")
|
827
|
+
end
|
828
|
+
|
829
|
+
it "raises an error if given non-hash options" do
|
830
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
831
|
+
|
832
|
+
expect { r.full_match("fooaa", "not a hash") }.to raise_error(TypeError)
|
833
|
+
end
|
834
|
+
|
835
|
+
it "accepts options that can be coerced to a hash", :aggregate_failures do
|
836
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
837
|
+
|
838
|
+
m = r.full_match("fooaa", nil)
|
839
|
+
expect(m[1]).to eq("oo")
|
840
|
+
|
841
|
+
m = r.full_match("fooaa", [])
|
842
|
+
expect(m[1]).to eq("oo")
|
843
|
+
end
|
844
|
+
|
845
|
+
it "accepts anything that can be coerced to a string" do
|
846
|
+
r = RE2::Regexp.new('f(o+)(a+)')
|
847
|
+
|
848
|
+
expect(r.full_match(StringLike.new("fooaa"), submatches: 0)).to eq(true)
|
849
|
+
end
|
850
|
+
|
851
|
+
it "does not allow the anchor to be overridden" do
|
852
|
+
r = RE2::Regexp.new('(\d+)')
|
853
|
+
|
854
|
+
expect(r.full_match('ruby:1234', anchor: :unanchored)).to be_nil
|
855
|
+
end
|
856
|
+
end
|
478
857
|
end
|