re2 2.28.0-aarch64-linux-gnu → 2.29.0-aarch64-linux-gnu
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 +11 -1
- data/ext/re2/re2.cc +117 -16
- data/lib/3.1/re2.so +0 -0
- data/lib/3.2/re2.so +0 -0
- data/lib/3.3/re2.so +0 -0
- data/lib/3.4/re2.so +0 -0
- data/lib/4.0/re2.so +0 -0
- data/lib/re2/match_data.rb +47 -0
- data/lib/re2/regexp.rb +43 -0
- data/lib/re2/version.rb +1 -1
- data/lib/re2.rb +1 -0
- data/re2.gemspec +1 -0
- data/spec/re2/match_data_spec.rb +193 -0
- data/spec/re2/regexp_spec.rb +154 -21
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1125158fafd16154fa094bd9fd9ac6933a9d0517d8a0d844db645667a543072
|
|
4
|
+
data.tar.gz: dd096ad81b773eb87c568f7647935f3be79964225edb3093949af3164b10a5d4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 39473b83200240c8654f3b6c5dff051c9a8a99797fd1fe948019ce6117b4204edd1f05e36cf2702f46f4e2a90957f9fcf1bca113896909eb6e485a36b49ab8af
|
|
7
|
+
data.tar.gz: 11b17f1e714db91c173a2196bea55de38a4db02d79d80ff3e8c12853e866a0290fa48c95a845e08025c60d841ba1a3417e3c2b9ec38e12c10fd68105824a1f6c
|
data/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Python".
|
|
|
6
6
|
|
|
7
7
|
[](https://github.com/mudge/re2/actions)
|
|
8
8
|
|
|
9
|
-
**Current version:** 2.
|
|
9
|
+
**Current version:** 2.29.0
|
|
10
10
|
**Bundled RE2 version:** libre2.11 (2025-11-05)
|
|
11
11
|
|
|
12
12
|
```ruby
|
|
@@ -232,6 +232,14 @@ m.offset(1) #=> [4, 7]
|
|
|
232
232
|
m.match_length(1) #=> 3
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
+
As RE2 works in bytes, the [`byteoffset`](https://mudge.name/re2/RE2/MatchData.html#byteoffset-instance_method), [`bytebegin`](https://mudge.name/re2/RE2/MatchData.html#bytebegin-instance_method) and [`byteend`](https://mudge.name/re2/RE2/MatchData.html#byteend-instance_method) of a match are cheaper to retrieve than their character equivalents:
|
|
236
|
+
|
|
237
|
+
```ruby
|
|
238
|
+
m = RE2::Regexp.new('(Ruby)').partial_match("I ♥ Ruby")
|
|
239
|
+
m.offset(1) #=> [4, 8]
|
|
240
|
+
m.byteoffset(1) #=> [6, 10]
|
|
241
|
+
```
|
|
242
|
+
|
|
235
243
|
`RE2::MatchData` objects can also be used with Ruby's [pattern matching](https://docs.ruby-lang.org/en/3.2/syntax/pattern_matching_rdoc.html):
|
|
236
244
|
|
|
237
245
|
```ruby
|
|
@@ -483,6 +491,8 @@ Alternatively, you can set the `RE2_USE_SYSTEM_LIBRARIES` environment variable i
|
|
|
483
491
|
when passing strings with null bytes.
|
|
484
492
|
* Thanks to [Maciej Gajewski](https://github.com/konieczkow) for helping
|
|
485
493
|
confirm issues with GC compaction and mutable strings.
|
|
494
|
+
* Thanks to [Konstantin Haase](https://github.com/rkh) for reporting that
|
|
495
|
+
`RE2::Regexp` shouldn't implement `to_str`.
|
|
486
496
|
|
|
487
497
|
## Contact
|
|
488
498
|
|
data/ext/re2/re2.cc
CHANGED
|
@@ -713,11 +713,11 @@ static VALUE re2_matchdata_begin(const VALUE self, VALUE n) {
|
|
|
713
713
|
re2::StringPiece *match = re2_matchdata_find_match(n, self);
|
|
714
714
|
if (match == nullptr) {
|
|
715
715
|
return Qnil;
|
|
716
|
-
} else {
|
|
717
|
-
long offset = match->data() - RSTRING_PTR(m->text);
|
|
718
|
-
|
|
719
|
-
return LONG2NUM(rb_str_sublen(m->text, offset));
|
|
720
716
|
}
|
|
717
|
+
|
|
718
|
+
long offset = match->data() - RSTRING_PTR(m->text);
|
|
719
|
+
|
|
720
|
+
return LONG2NUM(rb_str_sublen(m->text, offset));
|
|
721
721
|
}
|
|
722
722
|
|
|
723
723
|
/*
|
|
@@ -738,11 +738,11 @@ static VALUE re2_matchdata_end(const VALUE self, VALUE n) {
|
|
|
738
738
|
re2::StringPiece *match = re2_matchdata_find_match(n, self);
|
|
739
739
|
if (match == nullptr) {
|
|
740
740
|
return Qnil;
|
|
741
|
-
} else {
|
|
742
|
-
long offset = (match->data() - RSTRING_PTR(m->text)) + match->size();
|
|
743
|
-
|
|
744
|
-
return LONG2NUM(rb_str_sublen(m->text, offset));
|
|
745
741
|
}
|
|
742
|
+
|
|
743
|
+
long offset = (match->data() - RSTRING_PTR(m->text)) + match->size();
|
|
744
|
+
|
|
745
|
+
return LONG2NUM(rb_str_sublen(m->text, offset));
|
|
746
746
|
}
|
|
747
747
|
|
|
748
748
|
/*
|
|
@@ -830,6 +830,85 @@ static VALUE re2_matchdata_offset(const VALUE self, VALUE n) {
|
|
|
830
830
|
return array;
|
|
831
831
|
}
|
|
832
832
|
|
|
833
|
+
/*
|
|
834
|
+
* Returns the byte offset of the start of the nth element of the
|
|
835
|
+
* {RE2::MatchData}, like Ruby's `MatchData#bytebegin`. This is cheaper than
|
|
836
|
+
* {RE2::MatchData#begin} as it does not need to count characters.
|
|
837
|
+
*
|
|
838
|
+
* @param [Integer, String, Symbol] n the name or number of the submatch
|
|
839
|
+
* @return [Integer, nil] the byte offset of the start of the match or `nil` if
|
|
840
|
+
* there is no such submatch
|
|
841
|
+
* @example
|
|
842
|
+
* m = RE2::Regexp.new('(Ruby)').partial_match("I ♥ Ruby")
|
|
843
|
+
* m.bytebegin(0) #=> 6
|
|
844
|
+
* m.begin(0) #=> 4
|
|
845
|
+
*/
|
|
846
|
+
static VALUE re2_matchdata_bytebegin(const VALUE self, VALUE n) {
|
|
847
|
+
re2_matchdata *m = unwrap_re2_matchdata(self);
|
|
848
|
+
|
|
849
|
+
re2::StringPiece *match = re2_matchdata_find_match(n, self);
|
|
850
|
+
if (match == nullptr) {
|
|
851
|
+
return Qnil;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
return LONG2NUM(match->data() - RSTRING_PTR(m->text));
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/*
|
|
858
|
+
* Returns the byte offset of the byte following the end of the nth element of
|
|
859
|
+
* the {RE2::MatchData}, like Ruby's `MatchData#byteend`. This is cheaper than
|
|
860
|
+
* {RE2::MatchData#end} as it does not need to count characters.
|
|
861
|
+
*
|
|
862
|
+
* @param [Integer, String, Symbol] n the name or number of the match
|
|
863
|
+
* @return [Integer, nil] the byte offset of the byte following the end of the
|
|
864
|
+
* match or `nil` if there is no such match
|
|
865
|
+
* @example
|
|
866
|
+
* m = RE2::Regexp.new('(Ruby)').partial_match("I ♥ Ruby")
|
|
867
|
+
* m.byteend(0) #=> 10
|
|
868
|
+
* m.end(0) #=> 8
|
|
869
|
+
*/
|
|
870
|
+
static VALUE re2_matchdata_byteend(const VALUE self, VALUE n) {
|
|
871
|
+
re2_matchdata *m = unwrap_re2_matchdata(self);
|
|
872
|
+
|
|
873
|
+
re2::StringPiece *match = re2_matchdata_find_match(n, self);
|
|
874
|
+
if (match == nullptr) {
|
|
875
|
+
return Qnil;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
return LONG2NUM((match->data() - RSTRING_PTR(m->text)) + match->size());
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/*
|
|
882
|
+
* Returns a two-element array containing the beginning and ending byte
|
|
883
|
+
* offsets of the nth match, like Ruby's `MatchData#byteoffset`. This is
|
|
884
|
+
* cheaper than {RE2::MatchData#offset} as it does not need to count
|
|
885
|
+
* characters.
|
|
886
|
+
*
|
|
887
|
+
* @param [Integer, String, Symbol] n the name or number of the match
|
|
888
|
+
* @return [Array<Integer>, nil] a two-element array with the beginning and
|
|
889
|
+
* ending byte offsets of the match or `nil` if there is no such match
|
|
890
|
+
* @example
|
|
891
|
+
* m = RE2::Regexp.new('(Ruby)').partial_match("I ♥ Ruby")
|
|
892
|
+
* m.byteoffset(0) #=> [6, 10]
|
|
893
|
+
* m.offset(0) #=> [4, 8]
|
|
894
|
+
*/
|
|
895
|
+
static VALUE re2_matchdata_byteoffset(const VALUE self, VALUE n) {
|
|
896
|
+
re2_matchdata *m = unwrap_re2_matchdata(self);
|
|
897
|
+
|
|
898
|
+
re2::StringPiece *match = re2_matchdata_find_match(n, self);
|
|
899
|
+
if (match == nullptr) {
|
|
900
|
+
return Qnil;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
long start = match->data() - RSTRING_PTR(m->text);
|
|
904
|
+
|
|
905
|
+
VALUE array = rb_ary_new2(2);
|
|
906
|
+
rb_ary_push(array, LONG2NUM(start));
|
|
907
|
+
rb_ary_push(array, LONG2NUM(start + match->size()));
|
|
908
|
+
|
|
909
|
+
return array;
|
|
910
|
+
}
|
|
911
|
+
|
|
833
912
|
/*
|
|
834
913
|
* Returns the length of the nth match in characters. This is equivalent to
|
|
835
914
|
* `m[n].length` but without allocating a new string.
|
|
@@ -1804,7 +1883,7 @@ static VALUE re2_regexp_named_capturing_groups(const VALUE self) {
|
|
|
1804
1883
|
* Returns either `true` or `false` indicating whether a successful match was
|
|
1805
1884
|
* made if the pattern contains no capturing groups.
|
|
1806
1885
|
*
|
|
1807
|
-
* @param [String] text the text to search
|
|
1886
|
+
* @param [String, Symbol, nil] text the text to search; `nil` returns `nil`
|
|
1808
1887
|
* @return [RE2::MatchData, nil] if the pattern contains capturing groups
|
|
1809
1888
|
* @return [Boolean] if the pattern does not contain capturing groups
|
|
1810
1889
|
* @raise [NoMemoryError] if there was not enough memory to allocate the submatches
|
|
@@ -1822,7 +1901,7 @@ static VALUE re2_regexp_named_capturing_groups(const VALUE self) {
|
|
|
1822
1901
|
* specific number of submatches to extract (padded with `nil`s if
|
|
1823
1902
|
* necessary).
|
|
1824
1903
|
*
|
|
1825
|
-
* @param [String] text the text to search
|
|
1904
|
+
* @param [String, Symbol, nil] text the text to search; `nil` returns `nil`
|
|
1826
1905
|
* @param [Hash] options the options with which to perform the match
|
|
1827
1906
|
* @option options [Integer] :startpos (0) offset at which to start matching
|
|
1828
1907
|
* @option options [Integer] :endpos offset at which to stop matching, defaults to the text length
|
|
@@ -1855,7 +1934,7 @@ static VALUE re2_regexp_named_capturing_groups(const VALUE self) {
|
|
|
1855
1934
|
* @deprecated Legacy syntax for matching against `text` with a specific
|
|
1856
1935
|
* number of submatches to extract. Use `match(text, submatches: n)` instead.
|
|
1857
1936
|
*
|
|
1858
|
-
* @param [String] text the text to search
|
|
1937
|
+
* @param [String, Symbol, nil] text the text to search; `nil` returns `nil`
|
|
1859
1938
|
* @param [Integer] submatches the number of submatches to extract
|
|
1860
1939
|
* @return [RE2::MatchData, nil] if extracting any submatches
|
|
1861
1940
|
* @return [Boolean] if not extracting any submatches
|
|
@@ -1874,6 +1953,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
|
|
|
1874
1953
|
|
|
1875
1954
|
rb_scan_args(argc, argv, "11", &text, &options);
|
|
1876
1955
|
|
|
1956
|
+
if (NIL_P(text)) {
|
|
1957
|
+
return Qnil;
|
|
1958
|
+
}
|
|
1959
|
+
if (SYMBOL_P(text)) {
|
|
1960
|
+
text = rb_sym2str(text);
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1877
1963
|
/* Coerce and freeze text to prevent mutation. */
|
|
1878
1964
|
StringValue(text);
|
|
1879
1965
|
text = rb_str_new_frozen(text);
|
|
@@ -2020,11 +2106,17 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
|
|
|
2020
2106
|
* {https://github.com/google/re2/blob/bc0faab533e2b27b85b8ad312abf061e33ed6b5d/re2/re2.h#L413-L427
|
|
2021
2107
|
* `PartialMatch`}.
|
|
2022
2108
|
*
|
|
2023
|
-
* @param [String] text the text to search
|
|
2109
|
+
* @param [String, Symbol, nil] text the text to search; `nil` returns `false`
|
|
2024
2110
|
* @return [Boolean] whether the match was successful
|
|
2025
2111
|
* @raise [TypeError] if text cannot be coerced to a `String`
|
|
2026
2112
|
*/
|
|
2027
2113
|
static VALUE re2_regexp_match_p(const VALUE self, VALUE text) {
|
|
2114
|
+
if (NIL_P(text)) {
|
|
2115
|
+
return Qfalse;
|
|
2116
|
+
}
|
|
2117
|
+
if (SYMBOL_P(text)) {
|
|
2118
|
+
text = rb_sym2str(text);
|
|
2119
|
+
}
|
|
2028
2120
|
StringValue(text);
|
|
2029
2121
|
text = rb_str_new_frozen(text);
|
|
2030
2122
|
|
|
@@ -2041,11 +2133,17 @@ static VALUE re2_regexp_match_p(const VALUE self, VALUE text) {
|
|
|
2041
2133
|
* {https://github.com/google/re2/blob/bc0faab533e2b27b85b8ad312abf061e33ed6b5d/re2/re2.h#L376-L411
|
|
2042
2134
|
* `FullMatch`}.
|
|
2043
2135
|
*
|
|
2044
|
-
* @param [String] text the text to search
|
|
2136
|
+
* @param [String, Symbol, nil] text the text to search; `nil` returns `false`
|
|
2045
2137
|
* @return [Boolean] whether the match was successful
|
|
2046
2138
|
* @raise [TypeError] if text cannot be coerced to a `String`
|
|
2047
2139
|
*/
|
|
2048
2140
|
static VALUE re2_regexp_full_match_p(const VALUE self, VALUE text) {
|
|
2141
|
+
if (NIL_P(text)) {
|
|
2142
|
+
return Qfalse;
|
|
2143
|
+
}
|
|
2144
|
+
if (SYMBOL_P(text)) {
|
|
2145
|
+
text = rb_sym2str(text);
|
|
2146
|
+
}
|
|
2049
2147
|
StringValue(text);
|
|
2050
2148
|
text = rb_str_new_frozen(text);
|
|
2051
2149
|
|
|
@@ -2800,6 +2898,12 @@ extern "C" void Init_re2(void) {
|
|
|
2800
2898
|
RUBY_METHOD_FUNC(re2_matchdata_post_match), 0);
|
|
2801
2899
|
rb_define_method(re2_cMatchData, "offset",
|
|
2802
2900
|
RUBY_METHOD_FUNC(re2_matchdata_offset), 1);
|
|
2901
|
+
rb_define_method(re2_cMatchData, "bytebegin",
|
|
2902
|
+
RUBY_METHOD_FUNC(re2_matchdata_bytebegin), 1);
|
|
2903
|
+
rb_define_method(re2_cMatchData, "byteend",
|
|
2904
|
+
RUBY_METHOD_FUNC(re2_matchdata_byteend), 1);
|
|
2905
|
+
rb_define_method(re2_cMatchData, "byteoffset",
|
|
2906
|
+
RUBY_METHOD_FUNC(re2_matchdata_byteoffset), 1);
|
|
2803
2907
|
rb_define_method(re2_cMatchData, "match_length",
|
|
2804
2908
|
RUBY_METHOD_FUNC(re2_matchdata_match_length), 1);
|
|
2805
2909
|
rb_define_method(re2_cMatchData, "[]", RUBY_METHOD_FUNC(re2_matchdata_aref),
|
|
@@ -2866,14 +2970,11 @@ extern "C" void Init_re2(void) {
|
|
|
2866
2970
|
rb_define_method(re2_cRegexp, "partial_match?",
|
|
2867
2971
|
RUBY_METHOD_FUNC(re2_regexp_match_p), 1);
|
|
2868
2972
|
rb_define_method(re2_cRegexp, "=~", RUBY_METHOD_FUNC(re2_regexp_match_p), 1);
|
|
2869
|
-
rb_define_method(re2_cRegexp, "===", RUBY_METHOD_FUNC(re2_regexp_match_p), 1);
|
|
2870
2973
|
rb_define_method(re2_cRegexp, "full_match?",
|
|
2871
2974
|
RUBY_METHOD_FUNC(re2_regexp_full_match_p), 1);
|
|
2872
2975
|
rb_define_method(re2_cRegexp, "scan",
|
|
2873
2976
|
RUBY_METHOD_FUNC(re2_regexp_scan), 1);
|
|
2874
2977
|
rb_define_method(re2_cRegexp, "to_s", RUBY_METHOD_FUNC(re2_regexp_to_s), 0);
|
|
2875
|
-
rb_define_method(re2_cRegexp, "to_str", RUBY_METHOD_FUNC(re2_regexp_to_s),
|
|
2876
|
-
0);
|
|
2877
2978
|
rb_define_method(re2_cRegexp, "pattern", RUBY_METHOD_FUNC(re2_regexp_to_s),
|
|
2878
2979
|
0);
|
|
2879
2980
|
rb_define_method(re2_cRegexp, "source", RUBY_METHOD_FUNC(re2_regexp_to_s),
|
data/lib/3.1/re2.so
CHANGED
|
Binary file
|
data/lib/3.2/re2.so
CHANGED
|
Binary file
|
data/lib/3.3/re2.so
CHANGED
|
Binary file
|
data/lib/3.4/re2.so
CHANGED
|
Binary file
|
data/lib/4.0/re2.so
CHANGED
|
Binary file
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# re2 (https://github.com/mudge/re2)
|
|
4
|
+
# Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
|
|
5
|
+
# backtracking regular expression engines like those used in PCRE, Perl, and
|
|
6
|
+
# Python".
|
|
7
|
+
#
|
|
8
|
+
# Copyright (c) 2010, Paul Mucur (https://mudge.name)
|
|
9
|
+
# Released under the BSD Licence, please see LICENSE.txt
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
module RE2
|
|
13
|
+
class MatchData
|
|
14
|
+
# Return whether this match has the same regular expression, text, and
|
|
15
|
+
# submatch offsets as another {RE2::MatchData}, like Ruby's own
|
|
16
|
+
# `MatchData#==`.
|
|
17
|
+
#
|
|
18
|
+
# @param [Object] other the object to compare against
|
|
19
|
+
# @return [Boolean] whether the two matches are equal
|
|
20
|
+
# @example
|
|
21
|
+
# re = RE2::Regexp.new('(\d+)')
|
|
22
|
+
# re.match("abc 123") == re.match("abc 123") #=> true
|
|
23
|
+
# re.match("abc 123") == re.match("123 abc") #=> false
|
|
24
|
+
def ==(other)
|
|
25
|
+
other.is_a?(RE2::MatchData) &&
|
|
26
|
+
regexp == other.regexp &&
|
|
27
|
+
string == other.string &&
|
|
28
|
+
byteoffsets == other.byteoffsets
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias_method :eql?, :==
|
|
32
|
+
|
|
33
|
+
# Return a hash based on the regular expression, text, and submatch offsets
|
|
34
|
+
# so that equal {RE2::MatchData}s can be used as Hash keys.
|
|
35
|
+
#
|
|
36
|
+
# @return [Integer] the hash of the match
|
|
37
|
+
def hash
|
|
38
|
+
[regexp, string, byteoffsets].hash
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
protected
|
|
42
|
+
|
|
43
|
+
def byteoffsets
|
|
44
|
+
Array.new(size) { |i| byteoffset(i) }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/re2/regexp.rb
CHANGED
|
@@ -68,5 +68,48 @@ module RE2
|
|
|
68
68
|
def full_match(text, options = {})
|
|
69
69
|
match(text, Hash(options).merge(anchor: :anchor_both))
|
|
70
70
|
end
|
|
71
|
+
|
|
72
|
+
# Match the pattern against any substring of the given `text`, returning
|
|
73
|
+
# `false` if it is not a `String`, `Symbol`, or object responding to
|
|
74
|
+
# `to_str` so that an {RE2::Regexp} can be used in a `case` statement like
|
|
75
|
+
# Ruby's own `Regexp#===`.
|
|
76
|
+
#
|
|
77
|
+
# @param [Object] text the text to search; anything other than a `String`,
|
|
78
|
+
# `Symbol`, or object responding to `to_str` returns `false`
|
|
79
|
+
# @return [Boolean] whether the match was successful
|
|
80
|
+
# @example
|
|
81
|
+
# case "bob 123"
|
|
82
|
+
# when RE2::Regexp.new('\d+')
|
|
83
|
+
# "numbers"
|
|
84
|
+
# end
|
|
85
|
+
def ===(text)
|
|
86
|
+
text = text.to_s if text.is_a?(Symbol)
|
|
87
|
+
text = ::String.try_convert(text)
|
|
88
|
+
return false unless text
|
|
89
|
+
|
|
90
|
+
match?(text)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Return whether this regular expression has the same pattern and options
|
|
94
|
+
# as another {RE2::Regexp}.
|
|
95
|
+
#
|
|
96
|
+
# @param [Object] other the object to compare against
|
|
97
|
+
# @return [Boolean] whether the two regular expressions are equal
|
|
98
|
+
# @example
|
|
99
|
+
# RE2::Regexp.new('abc') == RE2::Regexp.new('abc') #=> true
|
|
100
|
+
# RE2::Regexp.new('abc') == RE2::Regexp.new('abc', case_sensitive: false) #=> false
|
|
101
|
+
def ==(other)
|
|
102
|
+
other.is_a?(RE2::Regexp) && source == other.source && options == other.options
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
alias_method :eql?, :==
|
|
106
|
+
|
|
107
|
+
# Return a hash based on the pattern and options so that equal
|
|
108
|
+
# {RE2::Regexp}s can be used as Hash keys.
|
|
109
|
+
#
|
|
110
|
+
# @return [Integer] the hash of the regular expression
|
|
111
|
+
def hash
|
|
112
|
+
[source, options].hash
|
|
113
|
+
end
|
|
71
114
|
end
|
|
72
115
|
end
|
data/lib/re2/version.rb
CHANGED
data/lib/re2.rb
CHANGED
data/re2.gemspec
CHANGED
data/spec/re2/match_data_spec.rb
CHANGED
|
@@ -632,6 +632,108 @@ RSpec.describe RE2::MatchData do
|
|
|
632
632
|
end
|
|
633
633
|
end
|
|
634
634
|
|
|
635
|
+
describe "#bytebegin" do
|
|
636
|
+
it "returns the byte offset of the start of a match by index" do
|
|
637
|
+
md = RE2::Regexp.new('(Ruby)').match("I ♥ Ruby")
|
|
638
|
+
|
|
639
|
+
expect(md.bytebegin(0)).to eq(6)
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
it "returns the byte offset of the start of a submatch by string name" do
|
|
643
|
+
md = RE2::Regexp.new('(?P<word>Ruby)').match("I ♥ Ruby")
|
|
644
|
+
|
|
645
|
+
expect(md.bytebegin("word")).to eq(6)
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
it "returns the byte offset of the start of a submatch by symbol name" do
|
|
649
|
+
md = RE2::Regexp.new('(?P<word>Ruby)').match("I ♥ Ruby")
|
|
650
|
+
|
|
651
|
+
expect(md.bytebegin(:word)).to eq(6)
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
it "returns nil for an unmatched submatch" do
|
|
655
|
+
md = RE2::Regexp.new('a(b)?').match("ac")
|
|
656
|
+
|
|
657
|
+
expect(md.bytebegin(1)).to be_nil
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
it "returns nil for a nonexistent submatch" do
|
|
661
|
+
md = RE2::Regexp.new('(a)').match("a")
|
|
662
|
+
|
|
663
|
+
expect(md.bytebegin(5)).to be_nil
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
it "raises an error when called on an uninitialized object" do
|
|
667
|
+
expect { described_class.allocate.bytebegin(0) }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
describe "#byteend" do
|
|
672
|
+
it "returns the byte offset after the end of a match by index" do
|
|
673
|
+
md = RE2::Regexp.new('(Ruby)').match("I ♥ Ruby")
|
|
674
|
+
|
|
675
|
+
expect(md.byteend(0)).to eq(10)
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
it "returns the byte offset after the end of a submatch by string name" do
|
|
679
|
+
md = RE2::Regexp.new('(?P<heart>♥)').match("I ♥ Ruby")
|
|
680
|
+
|
|
681
|
+
expect(md.byteend("heart")).to eq(5)
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
it "returns the byte offset after the end of a submatch by symbol name" do
|
|
685
|
+
md = RE2::Regexp.new('(?P<heart>♥)').match("I ♥ Ruby")
|
|
686
|
+
|
|
687
|
+
expect(md.byteend(:heart)).to eq(5)
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
it "returns nil for an unmatched submatch" do
|
|
691
|
+
md = RE2::Regexp.new('a(b)?').match("ac")
|
|
692
|
+
|
|
693
|
+
expect(md.byteend(1)).to be_nil
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
it "raises an error when called on an uninitialized object" do
|
|
697
|
+
expect { described_class.allocate.byteend(0) }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
describe "#byteoffset" do
|
|
702
|
+
it "returns the byte offsets of a match by index" do
|
|
703
|
+
md = RE2::Regexp.new('(Ruby)').match("I ♥ Ruby")
|
|
704
|
+
|
|
705
|
+
expect(md.byteoffset(0)).to eq([6, 10])
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
it "returns the byte offsets of a submatch by string name" do
|
|
709
|
+
md = RE2::Regexp.new('(?P<heart>♥)').match("I ♥ Ruby")
|
|
710
|
+
|
|
711
|
+
expect(md.byteoffset("heart")).to eq([2, 5])
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
it "returns the byte offsets of a submatch by symbol name" do
|
|
715
|
+
md = RE2::Regexp.new('(?P<heart>♥)').match("I ♥ Ruby")
|
|
716
|
+
|
|
717
|
+
expect(md.byteoffset(:heart)).to eq([2, 5])
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
it "can be used to slice the original string by bytes" do
|
|
721
|
+
md = RE2::Regexp.new('(Ruby)').match("I ♥ Ruby")
|
|
722
|
+
|
|
723
|
+
expect(md.string.byteslice(*md.byteoffset(1))).to eq("Ruby")
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
it "returns nil for an unmatched submatch" do
|
|
727
|
+
md = RE2::Regexp.new('a(b)?').match("ac")
|
|
728
|
+
|
|
729
|
+
expect(md.byteoffset(1)).to be_nil
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
it "raises an error when called on an uninitialized object" do
|
|
733
|
+
expect { described_class.allocate.byteoffset(0) }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
635
737
|
describe "#offset" do
|
|
636
738
|
it "returns the offset of a match by index" do
|
|
637
739
|
md = RE2::Regexp.new('ob (\d+)').match("bob 123")
|
|
@@ -1010,4 +1112,95 @@ RSpec.describe RE2::MatchData do
|
|
|
1010
1112
|
expect { described_class.allocate.deconstruct_keys(nil) }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
|
|
1011
1113
|
end
|
|
1012
1114
|
end
|
|
1115
|
+
|
|
1116
|
+
describe "#==" do
|
|
1117
|
+
it "returns true for matches with the same regexp, text, and offsets" do
|
|
1118
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1119
|
+
|
|
1120
|
+
expect(re.match("abc 123")).to eq(re.match("abc 123"))
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1123
|
+
it "returns true for matches against equal but distinct regexps" do
|
|
1124
|
+
md = RE2::Regexp.new('(\d+)').match("abc 123")
|
|
1125
|
+
|
|
1126
|
+
expect(md).to eq(RE2::Regexp.new('(\d+)').match("abc 123"))
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
it "returns true for matches against a copy of the text" do
|
|
1130
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1131
|
+
|
|
1132
|
+
expect(re.match("abc 123")).to eq(re.match("abc 123".dup))
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
it "returns true for matches with unmatched optional groups" do
|
|
1136
|
+
re = RE2::Regexp.new('a(b)?')
|
|
1137
|
+
|
|
1138
|
+
expect(re.match("ac")).to eq(re.match("ac"))
|
|
1139
|
+
end
|
|
1140
|
+
|
|
1141
|
+
it "returns false for matches against different text" do
|
|
1142
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1143
|
+
|
|
1144
|
+
expect(re.match("abc 123")).not_to eq(re.match("abc 456"))
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
it "returns false for the same captures at different offsets" do
|
|
1148
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1149
|
+
|
|
1150
|
+
expect(re.match("123 abc")).not_to eq(re.match("abc 123"))
|
|
1151
|
+
end
|
|
1152
|
+
|
|
1153
|
+
it "returns false for matches against regexps with different options" do
|
|
1154
|
+
md = RE2::Regexp.new('(abc)').match("abc")
|
|
1155
|
+
|
|
1156
|
+
expect(md).not_to eq(RE2::Regexp.new('(abc)', case_sensitive: false).match("abc"))
|
|
1157
|
+
end
|
|
1158
|
+
|
|
1159
|
+
it "returns false for matches with a different number of submatches" do
|
|
1160
|
+
re = RE2::Regexp.new('(a)(b)')
|
|
1161
|
+
|
|
1162
|
+
expect(re.match("ab")).not_to eq(re.match("ab", submatches: 1))
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
it "returns false for a non-MatchData" do
|
|
1166
|
+
expect(RE2::Regexp.new('(a)').match("a")).not_to eq("a")
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
it "is aliased to eql?" do
|
|
1170
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1171
|
+
|
|
1172
|
+
expect(re.match("abc 123")).to eql(re.match("abc 123"))
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
it "raises an error when called on an uninitialized object" do
|
|
1176
|
+
expect { described_class.allocate == RE2::Regexp.new('(a)').match("a") }.to raise_error(TypeError, /uninitialized RE2::MatchData/)
|
|
1177
|
+
end
|
|
1178
|
+
end
|
|
1179
|
+
|
|
1180
|
+
describe "#hash" do
|
|
1181
|
+
it "is the same for equal matches" do
|
|
1182
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1183
|
+
|
|
1184
|
+
expect(re.match("abc 123").hash).to eq(re.match("abc 123").hash)
|
|
1185
|
+
end
|
|
1186
|
+
|
|
1187
|
+
it "differs for matches at different offsets" do
|
|
1188
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1189
|
+
|
|
1190
|
+
expect(re.match("123 abc").hash).not_to eq(re.match("abc 123").hash)
|
|
1191
|
+
end
|
|
1192
|
+
|
|
1193
|
+
it "allows matches to be used as Hash keys" do
|
|
1194
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1195
|
+
hash = { re.match("abc 123") => :found }
|
|
1196
|
+
|
|
1197
|
+
expect(hash[re.match("abc 123")]).to eq(:found)
|
|
1198
|
+
end
|
|
1199
|
+
|
|
1200
|
+
it "allows matches to be deduplicated" do
|
|
1201
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1202
|
+
|
|
1203
|
+
expect([re.match("abc 123"), re.match("abc 123")].uniq.size).to eq(1)
|
|
1204
|
+
end
|
|
1205
|
+
end
|
|
1013
1206
|
end
|
data/spec/re2/regexp_spec.rb
CHANGED
|
@@ -241,24 +241,6 @@ RSpec.describe RE2::Regexp do
|
|
|
241
241
|
end
|
|
242
242
|
end
|
|
243
243
|
|
|
244
|
-
describe "#to_str" do
|
|
245
|
-
it "returns the original pattern" do
|
|
246
|
-
string = RE2::Regexp.new('w(o)(o)').to_str
|
|
247
|
-
|
|
248
|
-
expect(string).to eq("w(o)(o)")
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
it "returns the pattern even if invalid" do
|
|
252
|
-
string = RE2::Regexp.new('???', log_errors: false).to_str
|
|
253
|
-
|
|
254
|
-
expect(string).to eq("???")
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
it "raises an error when called on an uninitialized object" do
|
|
258
|
-
expect { described_class.allocate.to_str }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
|
|
262
244
|
describe "#pattern" do
|
|
263
245
|
it "returns the original pattern" do
|
|
264
246
|
pattern = RE2::Regexp.new('w(o)(o)').pattern
|
|
@@ -515,6 +497,18 @@ RSpec.describe RE2::Regexp do
|
|
|
515
497
|
expect(re.match("My name is Alice Bloggs")).to eq(true)
|
|
516
498
|
end
|
|
517
499
|
|
|
500
|
+
it "returns nil for nil" do
|
|
501
|
+
re = RE2::Regexp.new('.*')
|
|
502
|
+
|
|
503
|
+
expect(re.match(nil)).to be_nil
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
it "matches against symbols" do
|
|
507
|
+
re = RE2::Regexp.new('(\d+)')
|
|
508
|
+
|
|
509
|
+
expect(re.match(:abc123)).to be_a(RE2::MatchData)
|
|
510
|
+
end
|
|
511
|
+
|
|
518
512
|
it "supports matching against text containing null bytes" do
|
|
519
513
|
re = RE2::Regexp.new("a\0b")
|
|
520
514
|
|
|
@@ -536,7 +530,7 @@ RSpec.describe RE2::Regexp do
|
|
|
536
530
|
it "raises an exception when given text that cannot be coerced to a string" do
|
|
537
531
|
re = RE2::Regexp.new('My name is (\w+) (\w+)')
|
|
538
532
|
|
|
539
|
-
expect { re.match(
|
|
533
|
+
expect { re.match(0) }.to raise_error(TypeError)
|
|
540
534
|
end
|
|
541
535
|
|
|
542
536
|
it "returns nil with an invalid pattern" do
|
|
@@ -826,6 +820,18 @@ RSpec.describe RE2::Regexp do
|
|
|
826
820
|
expect(re.match?("My name is Alice Bloggs")).to eq(false)
|
|
827
821
|
end
|
|
828
822
|
|
|
823
|
+
it "returns false for nil" do
|
|
824
|
+
re = RE2::Regexp.new('.*')
|
|
825
|
+
|
|
826
|
+
expect(re.match?(nil)).to eq(false)
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
it "matches against symbols" do
|
|
830
|
+
re = RE2::Regexp.new('\d+')
|
|
831
|
+
|
|
832
|
+
expect(re.match?(:abc123)).to eq(true)
|
|
833
|
+
end
|
|
834
|
+
|
|
829
835
|
it "raises an exception if text cannot be coerced to a string" do
|
|
830
836
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
|
831
837
|
|
|
@@ -868,6 +874,18 @@ RSpec.describe RE2::Regexp do
|
|
|
868
874
|
expect(re.partial_match?("My name is Alice Bloggs")).to eq(false)
|
|
869
875
|
end
|
|
870
876
|
|
|
877
|
+
it "returns false for nil" do
|
|
878
|
+
re = RE2::Regexp.new('.*')
|
|
879
|
+
|
|
880
|
+
expect(re.partial_match?(nil)).to eq(false)
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
it "matches against symbols" do
|
|
884
|
+
re = RE2::Regexp.new('\d+')
|
|
885
|
+
|
|
886
|
+
expect(re.partial_match?(:abc123)).to eq(true)
|
|
887
|
+
end
|
|
888
|
+
|
|
871
889
|
it "raises an exception if text cannot be coerced to a string" do
|
|
872
890
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
|
873
891
|
|
|
@@ -910,6 +928,18 @@ RSpec.describe RE2::Regexp do
|
|
|
910
928
|
expect(re =~ "My name is Alice Bloggs").to eq(false)
|
|
911
929
|
end
|
|
912
930
|
|
|
931
|
+
it "returns false for nil" do
|
|
932
|
+
re = RE2::Regexp.new('.*')
|
|
933
|
+
|
|
934
|
+
expect(re =~ nil).to eq(false)
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
it "matches against symbols" do
|
|
938
|
+
re = RE2::Regexp.new('\d+')
|
|
939
|
+
|
|
940
|
+
expect(re =~ :abc123).to eq(true)
|
|
941
|
+
end
|
|
942
|
+
|
|
913
943
|
it "raises an exception if text cannot be coerced to a string" do
|
|
914
944
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
|
915
945
|
|
|
@@ -921,6 +951,52 @@ RSpec.describe RE2::Regexp do
|
|
|
921
951
|
end
|
|
922
952
|
end
|
|
923
953
|
|
|
954
|
+
describe "#==" do
|
|
955
|
+
it "returns true for regexps with the same pattern and options" do
|
|
956
|
+
expect(RE2::Regexp.new('a(b)', case_sensitive: false)).to eq(RE2::Regexp.new('a(b)', case_sensitive: false))
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
it "returns false for regexps with different patterns" do
|
|
960
|
+
expect(RE2::Regexp.new('a(b)')).not_to eq(RE2::Regexp.new('a(c)'))
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
it "returns false for regexps with different options" do
|
|
964
|
+
expect(RE2::Regexp.new('a(b)')).not_to eq(RE2::Regexp.new('a(b)', case_sensitive: false))
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
it "returns false for a String with the same pattern" do
|
|
968
|
+
expect(RE2::Regexp.new('a(b)')).not_to eq('a(b)')
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
it "is aliased to eql?" do
|
|
972
|
+
expect(RE2::Regexp.new('a(b)')).to eql(RE2::Regexp.new('a(b)'))
|
|
973
|
+
end
|
|
974
|
+
|
|
975
|
+
it "raises an error when called on an uninitialized object" do
|
|
976
|
+
expect { described_class.allocate == RE2::Regexp.new('a') }.to raise_error(TypeError, /uninitialized RE2::Regexp/)
|
|
977
|
+
end
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
describe "#hash" do
|
|
981
|
+
it "is the same for equal regexps" do
|
|
982
|
+
expect(RE2::Regexp.new('a(b)').hash).to eq(RE2::Regexp.new('a(b)').hash)
|
|
983
|
+
end
|
|
984
|
+
|
|
985
|
+
it "differs for regexps with different options" do
|
|
986
|
+
expect(RE2::Regexp.new('a(b)').hash).not_to eq(RE2::Regexp.new('a(b)', case_sensitive: false).hash)
|
|
987
|
+
end
|
|
988
|
+
|
|
989
|
+
it "allows regexps to be used as Hash keys" do
|
|
990
|
+
hash = { RE2::Regexp.new('a(b)') => :found }
|
|
991
|
+
|
|
992
|
+
expect(hash[RE2::Regexp.new('a(b)')]).to eq(:found)
|
|
993
|
+
end
|
|
994
|
+
|
|
995
|
+
it "allows regexps to be deduplicated" do
|
|
996
|
+
expect([RE2::Regexp.new('a'), RE2::Regexp.new('a')].uniq.size).to eq(1)
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
|
|
924
1000
|
describe "#===" do
|
|
925
1001
|
it "returns only true or false even if there are capturing groups", :aggregate_failures do
|
|
926
1002
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
|
@@ -935,10 +1011,31 @@ RSpec.describe RE2::Regexp do
|
|
|
935
1011
|
expect(re === "My name is Alice Bloggs").to eq(false)
|
|
936
1012
|
end
|
|
937
1013
|
|
|
938
|
-
it "
|
|
1014
|
+
it "matches against symbols" do
|
|
1015
|
+
re = RE2::Regexp.new('\d+')
|
|
1016
|
+
|
|
1017
|
+
expect(re === :abc123).to eq(true)
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
it "returns false if text cannot be coerced to a string" do
|
|
939
1021
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
|
940
1022
|
|
|
941
|
-
expect
|
|
1023
|
+
expect(re === 0).to eq(false)
|
|
1024
|
+
end
|
|
1025
|
+
|
|
1026
|
+
it "returns false for nil" do
|
|
1027
|
+
re = RE2::Regexp.new('.*')
|
|
1028
|
+
|
|
1029
|
+
expect(re === nil).to eq(false)
|
|
1030
|
+
end
|
|
1031
|
+
|
|
1032
|
+
it "can be used in a case statement" do
|
|
1033
|
+
result = case 123
|
|
1034
|
+
when RE2::Regexp.new('\d+') then :matched
|
|
1035
|
+
else :not_matched
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
expect(result).to eq(:not_matched)
|
|
942
1039
|
end
|
|
943
1040
|
|
|
944
1041
|
it "raises an error when called on an uninitialized object" do
|
|
@@ -967,6 +1064,18 @@ RSpec.describe RE2::Regexp do
|
|
|
967
1064
|
expect(re.full_match?("My name is Alice Bloggs")).to eq(false)
|
|
968
1065
|
end
|
|
969
1066
|
|
|
1067
|
+
it "returns false for nil" do
|
|
1068
|
+
re = RE2::Regexp.new('.*')
|
|
1069
|
+
|
|
1070
|
+
expect(re.full_match?(nil)).to eq(false)
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
it "matches against symbols" do
|
|
1074
|
+
re = RE2::Regexp.new('\w+')
|
|
1075
|
+
|
|
1076
|
+
expect(re.full_match?(:abc123)).to eq(true)
|
|
1077
|
+
end
|
|
1078
|
+
|
|
970
1079
|
it "raises an exception if text cannot be coerced to a string" do
|
|
971
1080
|
re = RE2::Regexp.new('My name is (\S+) (\S+)')
|
|
972
1081
|
|
|
@@ -1159,6 +1268,18 @@ RSpec.describe RE2::Regexp do
|
|
|
1159
1268
|
expect(r.partial_match("foo bar")).to eq(true)
|
|
1160
1269
|
end
|
|
1161
1270
|
|
|
1271
|
+
it "returns nil for nil" do
|
|
1272
|
+
re = RE2::Regexp.new('.*')
|
|
1273
|
+
|
|
1274
|
+
expect(re.partial_match(nil)).to be_nil
|
|
1275
|
+
end
|
|
1276
|
+
|
|
1277
|
+
it "matches against symbols" do
|
|
1278
|
+
re = RE2::Regexp.new('(\d+)')
|
|
1279
|
+
|
|
1280
|
+
expect(re.partial_match(:abc123)).to be_a(RE2::MatchData)
|
|
1281
|
+
end
|
|
1282
|
+
|
|
1162
1283
|
it "can set the number of submatches to extract", :aggregate_failures do
|
|
1163
1284
|
r = RE2::Regexp.new('f(o+)(a+)')
|
|
1164
1285
|
m = r.partial_match("fooaa bar", submatches: 1)
|
|
@@ -1219,6 +1340,18 @@ RSpec.describe RE2::Regexp do
|
|
|
1219
1340
|
expect(r.full_match("foo")).to eq(true)
|
|
1220
1341
|
end
|
|
1221
1342
|
|
|
1343
|
+
it "returns nil for nil" do
|
|
1344
|
+
re = RE2::Regexp.new('.*')
|
|
1345
|
+
|
|
1346
|
+
expect(re.full_match(nil)).to be_nil
|
|
1347
|
+
end
|
|
1348
|
+
|
|
1349
|
+
it "matches against symbols" do
|
|
1350
|
+
re = RE2::Regexp.new('(\w+)')
|
|
1351
|
+
|
|
1352
|
+
expect(re.full_match(:abc123)).to be_a(RE2::MatchData)
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1222
1355
|
it "can set the number of submatches to extract", :aggregate_failures do
|
|
1223
1356
|
r = RE2::Regexp.new('f(o+)(a+)')
|
|
1224
1357
|
m = r.full_match("fooaa", submatches: 1)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: re2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.29.0
|
|
5
5
|
platform: aarch64-linux-gnu
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Mucur
|
|
@@ -74,6 +74,7 @@ files:
|
|
|
74
74
|
- lib/3.4/re2.so
|
|
75
75
|
- lib/4.0/re2.so
|
|
76
76
|
- lib/re2.rb
|
|
77
|
+
- lib/re2/match_data.rb
|
|
77
78
|
- lib/re2/regexp.rb
|
|
78
79
|
- lib/re2/scanner.rb
|
|
79
80
|
- lib/re2/string.rb
|