re2 0.7.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -15
- data/Rakefile +4 -9
- data/ext/re2/extconf.rb +39 -18
- data/ext/re2/re2.cc +1 -1
- 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 +19 -21
- data/spec/re2/string_spec.rb +12 -13
- data/spec/re2_spec.rb +15 -19
- data/spec/spec_helper.rb +18 -2
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 118d0c677843bd7166804670d548504e6a30410b
|
4
|
+
data.tar.gz: 9efe563b54262ad28c5b71c2317b3f18117e2706
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07d895cafa392c75483586a37b44f57b5d5979b7473529c52eff05f3c6bccca3b11f8d406363ece9f3ab2ad02df4952031dcdb8104cdc275484666a0ceb7db01
|
7
|
+
data.tar.gz: 8147a0194f92a7850285339d9d81fe74b4865d12f67a1e64fa9db3eeec35c3adaaf4cfd97862f1d954b7b475b4dc4b0d01ef28dd10c3f39cba3338caac6ff51a
|
data/README.md
CHANGED
@@ -4,8 +4,8 @@ re2 [![Build Status](https://travis-ci.org/mudge/re2.svg?branch=master)](http://
|
|
4
4
|
A Ruby binding to [re2][], an "efficient, principled regular expression
|
5
5
|
library".
|
6
6
|
|
7
|
-
**Current version:** 0.
|
8
|
-
**Supported Ruby versions:** 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.0, Rubinius 2.2
|
7
|
+
**Current version:** 1.0.0
|
8
|
+
**Supported Ruby versions:** 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.0, 2.2, 2.3, Rubinius 2.2
|
9
9
|
|
10
10
|
Installation
|
11
11
|
------------
|
@@ -21,6 +21,8 @@ If you are using Debian, you can install the [libre2-dev][] package like so:
|
|
21
21
|
|
22
22
|
$ sudo apt-get install libre2-dev
|
23
23
|
|
24
|
+
Recent versions of re2 require a compiler with C++11 support such as [clang](http://clang.llvm.org/) 3.4 or [gcc](https://gcc.gnu.org/) 4.8.
|
25
|
+
|
24
26
|
If you are using a packaged Ruby distribution, make sure you also have the
|
25
27
|
Ruby header files installed such as those provided by the [ruby-dev][] package
|
26
28
|
on Debian and Ubuntu.
|
@@ -35,14 +37,17 @@ Documentation
|
|
35
37
|
Full documentation automatically generated from the latest version is
|
36
38
|
available at <http://mudge.name/re2/>.
|
37
39
|
|
38
|
-
|
39
|
-
[official syntax page][] for more
|
40
|
+
Note that re2's regular expression syntax differs from PCRE and Ruby's
|
41
|
+
built-in [`Regexp`][Regexp] library, see the [official syntax page][] for more
|
42
|
+
details.
|
40
43
|
|
41
44
|
Usage
|
42
45
|
-----
|
43
46
|
|
44
|
-
|
45
|
-
[
|
47
|
+
While re2 uses the same naming scheme as Ruby's built-in regular expression
|
48
|
+
library (with [`Regexp`](http://mudge.name/re2/RE2/Regexp.html) and
|
49
|
+
[`MatchData`](http://mudge.name/re2/RE2/MatchData.html)), its API is slightly
|
50
|
+
different:
|
46
51
|
|
47
52
|
```console
|
48
53
|
$ irb -rubygems
|
@@ -67,9 +72,11 @@ $ irb -rubygems
|
|
67
72
|
=> nil
|
68
73
|
```
|
69
74
|
|
70
|
-
As
|
71
|
-
|
72
|
-
|
75
|
+
As
|
76
|
+
[`RE2::Regexp.new`](http://mudge.name/re2/RE2/Regexp.html#initialize-instance_method)
|
77
|
+
(or `RE2::Regexp.compile`) can be quite verbose, a helper method has been
|
78
|
+
defined against `Kernel` so you can use a shorter version to create regular
|
79
|
+
expressions:
|
73
80
|
|
74
81
|
```console
|
75
82
|
> RE2('(\d+)')
|
@@ -123,7 +130,7 @@ Features
|
|
123
130
|
--------
|
124
131
|
|
125
132
|
* Pre-compiling regular expressions with
|
126
|
-
[`RE2::Regexp.new(re)`](
|
133
|
+
[`RE2::Regexp.new(re)`](https://github.com/google/re2/blob/2016-02-01/re2/re2.h#L100),
|
127
134
|
`RE2::Regexp.compile(re)` or `RE2(re)` (including specifying options, e.g.
|
128
135
|
`RE2::Regexp.new("pattern", :case_sensitive => false)`
|
129
136
|
|
@@ -152,21 +159,22 @@ Features
|
|
152
159
|
`pattern.replace_all(replacement, original)`
|
153
160
|
|
154
161
|
* Escaping regular expressions with
|
155
|
-
[`RE2.escape(unquoted)`](
|
162
|
+
[`RE2.escape(unquoted)`](https://github.com/google/re2/blob/2016-02-01/re2/re2.h#L418) and
|
156
163
|
`RE2.quote(unquoted)`
|
157
164
|
|
158
165
|
Contributions
|
159
166
|
-------------
|
160
167
|
|
161
|
-
Thanks to [Jason Woods](https://github.com/driskell) who contributed the
|
162
|
-
original implementations of `RE2::MatchData#begin` and `RE2::MatchData#end
|
168
|
+
* Thanks to [Jason Woods](https://github.com/driskell) who contributed the
|
169
|
+
original implementations of `RE2::MatchData#begin` and `RE2::MatchData#end`;
|
170
|
+
* Thanks to [Stefano Rivera](https://github.com/stefanor) who first contributed C++11 support.
|
163
171
|
|
164
172
|
Contact
|
165
173
|
-------
|
166
174
|
|
167
175
|
All feedback should go to the mailing list: <mailto:ruby.re2@librelist.com>
|
168
176
|
|
169
|
-
[re2]:
|
177
|
+
[re2]: https://github.com/google/re2
|
170
178
|
[gcc]: http://gcc.gnu.org/
|
171
179
|
[ruby-dev]: http://packages.debian.org/ruby-dev
|
172
180
|
[build-essential]: http://packages.debian.org/build-essential
|
@@ -174,5 +182,5 @@ All feedback should go to the mailing list: <mailto:ruby.re2@librelist.com>
|
|
174
182
|
[MatchData]: http://ruby-doc.org/core/classes/MatchData.html
|
175
183
|
[Homebrew]: http://mxcl.github.com/homebrew
|
176
184
|
[libre2-dev]: http://packages.debian.org/search?keywords=libre2-dev
|
177
|
-
[official syntax page]:
|
185
|
+
[official syntax page]: https://github.com/google/re2/wiki/Syntax
|
178
186
|
|
data/Rakefile
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
require 'rake/extensiontask'
|
2
|
-
require '
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
|
4
4
|
Rake::ExtensionTask.new('re2')
|
5
5
|
|
6
|
-
|
7
|
-
t.libs << "spec"
|
8
|
-
t.test_files = FileList["spec/**/*_spec.rb"]
|
9
|
-
t.verbose = true
|
10
|
-
end
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
7
|
|
12
|
-
task :
|
13
|
-
task :
|
14
|
-
task :default => :test
|
8
|
+
task :spec => :compile
|
9
|
+
task :default => :spec
|
15
10
|
|
data/ext/re2/extconf.rb
CHANGED
@@ -10,20 +10,46 @@ incl, lib = dir_config("re2", "/usr/local/include", "/usr/local/lib")
|
|
10
10
|
|
11
11
|
$CFLAGS << " -Wall -Wextra -funroll-loops"
|
12
12
|
|
13
|
+
# Pass -x c++ to force gcc to compile the test program
|
14
|
+
# as C++ (as it will end in .c by default).
|
15
|
+
compile_options = "-x c++"
|
16
|
+
|
13
17
|
have_library("stdc++")
|
14
18
|
have_header("stdint.h")
|
15
19
|
have_func("rb_str_sublen")
|
16
20
|
|
17
|
-
|
21
|
+
unless have_library("re2")
|
22
|
+
abort "You must have re2 installed and specified with --with-re2-dir, please see https://github.com/google/re2/wiki/Install"
|
23
|
+
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
# Recent versions of re2 now require a compiler with C++11 support
|
26
|
+
checking_for("re2 requires C++11 compiler") do
|
27
|
+
minimal_program = <<SRC
|
28
|
+
#include <re2/re2.h>
|
29
|
+
int main() { return 0; }
|
30
|
+
SRC
|
31
|
+
|
32
|
+
unless try_compile(minimal_program, compile_options)
|
33
|
+
if try_compile(minimal_program, compile_options + " -std=c++11")
|
34
|
+
compile_options << " -std=c++11"
|
35
|
+
$CPPFLAGS << " -std=c++11"
|
36
|
+
elsif try_compile(minimal_program, compile_options + " -std=c++0x")
|
37
|
+
compile_options << " -std=c++0x"
|
38
|
+
$CPPFLAGS << " -std=c++0x"
|
39
|
+
else
|
40
|
+
abort "Cannot compile re2 with your compiler: recent versions require C++11 support."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Determine which version of re2 the user has installed.
|
46
|
+
# Revision d9f8806c004d added an `endpos` argument to the
|
47
|
+
# generic Match() function.
|
48
|
+
#
|
49
|
+
# To test for this, try to compile a simple program that uses
|
50
|
+
# the newer form of Match() and set a flag if it is successful.
|
51
|
+
checking_for("RE2::Match() with endpos argument") do
|
52
|
+
test_re2_match_signature = <<SRC
|
27
53
|
#include <re2/re2.h>
|
28
54
|
|
29
55
|
int main() {
|
@@ -35,14 +61,9 @@ int main() {
|
|
35
61
|
}
|
36
62
|
SRC
|
37
63
|
|
38
|
-
|
39
|
-
|
40
|
-
if try_compile(test_re2_match_signature, "-x c++")
|
41
|
-
$defs.push("-DHAVE_ENDPOS_ARGUMENT")
|
42
|
-
end
|
64
|
+
if try_compile(test_re2_match_signature, compile_options)
|
65
|
+
$defs.push("-DHAVE_ENDPOS_ARGUMENT")
|
43
66
|
end
|
44
|
-
|
45
|
-
create_makefile("re2")
|
46
|
-
else
|
47
|
-
abort "You must have re2 installed and specified with --with-re2-dir, please see http://code.google.com/p/re2/wiki/Install"
|
48
67
|
end
|
68
|
+
|
69
|
+
create_makefile("re2")
|
data/ext/re2/re2.cc
CHANGED
data/spec/kernel_spec.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Kernel do
|
1
|
+
RSpec.describe Kernel do
|
4
2
|
describe "#RE2" do
|
5
3
|
it "returns an RE2::Regexp instance given a pattern" do
|
6
|
-
RE2('w(o)(o)').
|
4
|
+
expect(RE2('w(o)(o)')).to be_a(RE2::Regexp)
|
7
5
|
end
|
8
6
|
|
9
7
|
it "returns an RE2::Regexp instance given a pattern and options" do
|
10
8
|
re = RE2('w(o)(o)', :case_sensitive => false)
|
11
|
-
re.
|
12
|
-
re.
|
9
|
+
expect(re).to be_a(RE2::Regexp)
|
10
|
+
expect(re).to_not be_case_sensitive
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
data/spec/re2/match_data_spec.rb
CHANGED
@@ -1,94 +1,90 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe RE2::MatchData do
|
6
|
-
|
2
|
+
RSpec.describe RE2::MatchData do
|
7
3
|
describe "#to_a" do
|
8
4
|
it "is populated with the match and capturing groups" do
|
9
5
|
a = RE2::Regexp.new('w(o)(o)').match('woo').to_a
|
10
|
-
a.
|
6
|
+
expect(a).to eq(["woo", "o", "o"])
|
11
7
|
end
|
12
8
|
|
13
9
|
it "populates optional capturing groups with nil if they are missing" do
|
14
10
|
a = RE2::Regexp.new('(\d?)(a)(b)').match('ab').to_a
|
15
|
-
a.
|
11
|
+
expect(a).to eq(["ab", nil, "a", "b"])
|
16
12
|
end
|
17
13
|
end
|
18
14
|
|
19
15
|
describe "#[]" do
|
20
16
|
it "accesses capturing groups by numerical index" do
|
21
17
|
md = RE2::Regexp.new('(\d)(\d{2})').match("123")
|
22
|
-
md[1].
|
23
|
-
md[2].
|
18
|
+
expect(md[1]).to eq("1")
|
19
|
+
expect(md[2]).to eq("23")
|
24
20
|
end
|
25
21
|
|
26
22
|
it "has the whole match as the 0th item" do
|
27
23
|
md = RE2::Regexp.new('(\d)(\d{2})').match("123")
|
28
|
-
md[0].
|
24
|
+
expect(md[0]).to eq("123")
|
29
25
|
end
|
30
26
|
|
31
27
|
it "supports access by numerical ranges" do
|
32
28
|
md = RE2::Regexp.new('(\d+) (\d+) (\d+)').match("123 456 789")
|
33
|
-
md[1..3].
|
34
|
-
md[1...3].
|
29
|
+
expect(md[1..3]).to eq(["123", "456", "789"])
|
30
|
+
expect(md[1...3]).to eq(["123", "456"])
|
35
31
|
end
|
36
32
|
|
37
33
|
it "supports slicing" do
|
38
34
|
md = RE2::Regexp.new('(\d+) (\d+) (\d+)').match("123 456 789")
|
39
|
-
md[1, 3].
|
40
|
-
md[1, 2].
|
35
|
+
expect(md[1, 3]).to eq(["123", "456", "789"])
|
36
|
+
expect(md[1, 2]).to eq(["123", "456"])
|
41
37
|
end
|
42
38
|
|
43
39
|
it "returns nil if attempting to access non-existent capturing groups by index" do
|
44
40
|
md = RE2::Regexp.new('(\d+)').match('bob 123')
|
45
|
-
md[2].
|
46
|
-
md[3].
|
41
|
+
expect(md[2]).to be_nil
|
42
|
+
expect(md[3]).to be_nil
|
47
43
|
end
|
48
44
|
|
49
45
|
it "allows access by string names when there are named groups" do
|
50
46
|
md = RE2::Regexp.new('(?P<numbers>\d+)').match('bob 123')
|
51
|
-
md["numbers"].
|
47
|
+
expect(md["numbers"]).to eq("123")
|
52
48
|
end
|
53
49
|
|
54
50
|
it "allows access by symbol names when there are named groups" do
|
55
51
|
md = RE2::Regexp.new('(?P<numbers>\d+)').match('bob 123')
|
56
|
-
md[:numbers].
|
52
|
+
expect(md[:numbers]).to eq("123")
|
57
53
|
end
|
58
54
|
|
59
55
|
it "allows access by names and indices with mixed groups" do
|
60
56
|
md = RE2::Regexp.new('(?P<name>\w+)(\s*)(?P<numbers>\d+)').match("bob 123")
|
61
|
-
md["name"].
|
62
|
-
md[:name].
|
63
|
-
md[2].
|
64
|
-
md["numbers"].
|
65
|
-
md[:numbers].
|
57
|
+
expect(md["name"]).to eq("bob")
|
58
|
+
expect(md[:name]).to eq("bob")
|
59
|
+
expect(md[2]).to eq(" ")
|
60
|
+
expect(md["numbers"]).to eq("123")
|
61
|
+
expect(md[:numbers]).to eq("123")
|
66
62
|
end
|
67
63
|
|
68
64
|
it "returns nil if no such named group exists" do
|
69
65
|
md = RE2::Regexp.new('(\d+)').match("bob 123")
|
70
|
-
md["missing"].
|
71
|
-
md[:missing].
|
66
|
+
expect(md["missing"]).to be_nil
|
67
|
+
expect(md[:missing]).to be_nil
|
72
68
|
end
|
73
69
|
|
74
70
|
it "raises an error if given an inappropriate index" do
|
75
71
|
md = RE2::Regexp.new('(\d+)').match("bob 123")
|
76
|
-
|
72
|
+
expect { md[nil] }.to raise_error(TypeError)
|
77
73
|
end
|
78
74
|
|
79
75
|
if String.method_defined?(:encoding)
|
80
76
|
it "returns UTF-8 encoded strings by default" do
|
81
77
|
md = RE2::Regexp.new('(?P<name>\S+)').match("bob")
|
82
|
-
md[0].encoding.name.
|
83
|
-
md["name"].encoding.name.
|
84
|
-
md[:name].encoding.name.
|
78
|
+
expect(md[0].encoding.name).to eq("UTF-8")
|
79
|
+
expect(md["name"].encoding.name).to eq("UTF-8")
|
80
|
+
expect(md[:name].encoding.name).to eq("UTF-8")
|
85
81
|
end
|
86
82
|
|
87
83
|
it "returns Latin 1 strings encoding when utf-8 is false" do
|
88
84
|
md = RE2::Regexp.new('(?P<name>\S+)', :utf8 => false).match('bob')
|
89
|
-
md[0].encoding.name.
|
90
|
-
md["name"].encoding.name.
|
91
|
-
md[:name].encoding.name.
|
85
|
+
expect(md[0].encoding.name).to eq("ISO-8859-1")
|
86
|
+
expect(md["name"].encoding.name).to eq("ISO-8859-1")
|
87
|
+
expect(md[:name].encoding.name).to eq("ISO-8859-1")
|
92
88
|
end
|
93
89
|
end
|
94
90
|
end
|
@@ -96,32 +92,32 @@ describe RE2::MatchData do
|
|
96
92
|
describe "#string" do
|
97
93
|
it "returns the original string to match against" do
|
98
94
|
re = RE2::Regexp.new('(\D+)').match("bob")
|
99
|
-
re.string.
|
95
|
+
expect(re.string).to eq("bob")
|
100
96
|
end
|
101
97
|
|
102
98
|
it "returns a copy, not the actual original" do
|
103
99
|
string = "bob"
|
104
100
|
re = RE2::Regexp.new('(\D+)').match(string)
|
105
|
-
re.string.
|
101
|
+
expect(re.string).to_not equal(string)
|
106
102
|
end
|
107
103
|
|
108
104
|
it "returns a frozen string" do
|
109
105
|
re = RE2::Regexp.new('(\D+)').match("bob")
|
110
|
-
re.string.
|
106
|
+
expect(re.string).to be_frozen
|
111
107
|
end
|
112
108
|
end
|
113
109
|
|
114
110
|
describe "#size" do
|
115
111
|
it "returns the number of capturing groups plus the matching string" do
|
116
112
|
md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
|
117
|
-
md.size.
|
113
|
+
expect(md.size).to eq(3)
|
118
114
|
end
|
119
115
|
end
|
120
116
|
|
121
117
|
describe "#length" do
|
122
118
|
it "returns the number of capturing groups plus the matching string" do
|
123
119
|
md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
|
124
|
-
md.length.
|
120
|
+
expect(md.length).to eq(3)
|
125
121
|
end
|
126
122
|
end
|
127
123
|
|
@@ -129,26 +125,26 @@ describe RE2::MatchData do
|
|
129
125
|
it "returns the original RE2::Regexp used" do
|
130
126
|
re = RE2::Regexp.new('(\d+)')
|
131
127
|
md = re.match("123")
|
132
|
-
md.regexp.
|
128
|
+
expect(md.regexp).to equal(re)
|
133
129
|
end
|
134
130
|
end
|
135
131
|
|
136
132
|
describe "#inspect" do
|
137
133
|
it "returns a text representation of the object and indices" do
|
138
134
|
md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
|
139
|
-
md.inspect.
|
135
|
+
expect(md.inspect).to eq('#<RE2::MatchData "1234 56" 1:"1234" 2:"56">')
|
140
136
|
end
|
141
137
|
|
142
138
|
it "represents missing matches as nil" do
|
143
139
|
md = RE2::Regexp.new('(\d+) (\d+)?').match("1234 ")
|
144
|
-
md.inspect.
|
140
|
+
expect(md.inspect).to eq('#<RE2::MatchData "1234 " 1:"1234" 2:nil>')
|
145
141
|
end
|
146
142
|
end
|
147
143
|
|
148
144
|
describe "#to_s" do
|
149
145
|
it "returns the matching part of the original string" do
|
150
146
|
md = RE2::Regexp.new('(\d{2,5})').match("one two 23456")
|
151
|
-
md.to_s.
|
147
|
+
expect(md.to_s).to eq("23456")
|
152
148
|
end
|
153
149
|
end
|
154
150
|
|
@@ -156,53 +152,93 @@ describe RE2::MatchData do
|
|
156
152
|
it "allows the object to be expanded with an asterisk" do
|
157
153
|
md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
|
158
154
|
m1, m2, m3 = *md
|
159
|
-
m1.
|
160
|
-
m2.
|
161
|
-
m3.
|
155
|
+
expect(m1).to eq("1234 56")
|
156
|
+
expect(m2).to eq("1234")
|
157
|
+
expect(m3).to eq("56")
|
162
158
|
end
|
163
159
|
end
|
164
160
|
|
165
161
|
describe "#begin" do
|
166
162
|
it "returns the offset of the start of a match by index" do
|
167
163
|
md = RE2::Regexp.new('(wo{2})').match('a woohoo')
|
168
|
-
md.string[md.begin(0)..-1].
|
164
|
+
expect(md.string[md.begin(0)..-1]).to eq('woohoo')
|
169
165
|
end
|
170
166
|
|
171
167
|
it "returns the offset of the start of a match by string name" do
|
172
168
|
md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
|
173
|
-
md.string[md.begin('foo')..-1].
|
169
|
+
expect(md.string[md.begin('foo')..-1]).to eq('foobar')
|
174
170
|
end
|
175
171
|
|
176
172
|
it "returns the offset of the start of a match by symbol name" do
|
177
173
|
md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
|
178
|
-
md.string[md.begin(:foo)..-1].
|
174
|
+
expect(md.string[md.begin(:foo)..-1]).to eq('foobar')
|
179
175
|
end
|
180
176
|
|
181
177
|
it "returns the offset despite multibyte characters" do
|
182
178
|
md = RE2::Regexp.new('(Ruby)').match('I ♥ Ruby')
|
183
|
-
md.string[md.begin(0)..-1].
|
179
|
+
expect(md.string[md.begin(0)..-1]).to eq('Ruby')
|
180
|
+
end
|
181
|
+
|
182
|
+
it "returns nil for non-existent numerical matches" do
|
183
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
184
|
+
expect(md.begin(10)).to be_nil
|
185
|
+
end
|
186
|
+
|
187
|
+
it "returns nil for negative numerical matches" do
|
188
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
189
|
+
expect(md.begin(-4)).to be_nil
|
190
|
+
end
|
191
|
+
|
192
|
+
it "returns nil for non-existent named matches" do
|
193
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
194
|
+
expect(md.begin('foo')).to be_nil
|
195
|
+
end
|
196
|
+
|
197
|
+
it "returns nil for non-existent symbol named matches" do
|
198
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
199
|
+
expect(md.begin(:foo)).to be_nil
|
184
200
|
end
|
185
201
|
end
|
186
202
|
|
187
203
|
describe "#end" do
|
188
204
|
it "returns the offset of the character following the end of a match" do
|
189
205
|
md = RE2::Regexp.new('(wo{2})').match('a woohoo')
|
190
|
-
md.string[0...md.end(0)].
|
206
|
+
expect(md.string[0...md.end(0)]).to eq('a woo')
|
191
207
|
end
|
192
208
|
|
193
209
|
it "returns the offset of a match by string name" do
|
194
210
|
md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
|
195
|
-
md.string[0...md.end('foo')].
|
211
|
+
expect(md.string[0...md.end('foo')]).to eq('a foo')
|
196
212
|
end
|
197
213
|
|
198
214
|
it "returns the offset of a match by symbol name" do
|
199
215
|
md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
|
200
|
-
md.string[0...md.end(:foo)].
|
216
|
+
expect(md.string[0...md.end(:foo)]).to eq('a foo')
|
201
217
|
end
|
202
218
|
|
203
219
|
it "returns the offset despite multibyte characters" do
|
204
220
|
md = RE2::Regexp.new('(Ruby)').match('I ♥ Ruby')
|
205
|
-
md.string[0...md.end(0)].
|
221
|
+
expect(md.string[0...md.end(0)]).to eq('I ♥ Ruby')
|
222
|
+
end
|
223
|
+
|
224
|
+
it "returns nil for non-existent numerical matches" do
|
225
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
226
|
+
expect(md.end(10)).to be_nil
|
227
|
+
end
|
228
|
+
|
229
|
+
it "returns nil for negative numerical matches" do
|
230
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
231
|
+
expect(md.end(-4)).to be_nil
|
232
|
+
end
|
233
|
+
|
234
|
+
it "returns nil for non-existent named matches" do
|
235
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
236
|
+
expect(md.end('foo')).to be_nil
|
237
|
+
end
|
238
|
+
|
239
|
+
it "returns nil for non-existent symbol named matches" do
|
240
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
241
|
+
expect(md.end(:foo)).to be_nil
|
206
242
|
end
|
207
243
|
end
|
208
244
|
end
|