re2 0.7.0 → 1.0.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 +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 [](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
|