re2 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- re2
1
+ re2 [![Build Status](https://secure.travis-ci.org/mudge/re2.png?branch=master)](http://travis-ci.org/mudge/re2)
2
2
  ===
3
3
 
4
4
  A Ruby binding to [re2][], an "efficient, principled regular expression library".
@@ -6,7 +6,13 @@ A Ruby binding to [re2][], an "efficient, principled regular expression library"
6
6
  Installation
7
7
  ------------
8
8
 
9
- You will need [re2][] installed as well as a C++ compiler such as [gcc][] (on Debian and Ubuntu, this is provided by the [build-essential][] package).
9
+ You will need [re2][] installed as well as a C++ compiler such as [gcc][] (on Debian and Ubuntu, this is provided by the [build-essential][] package). If you are using Mac OS X, I recommend installing re2 with [Homebrew][] by running the following:
10
+
11
+ $ brew install --HEAD re2
12
+
13
+ If you are using Debian, you can install the [libre2-dev][] package like so:
14
+
15
+ $ sudo apt-get install libre2-dev
10
16
 
11
17
  If you are using a packaged Ruby distribution, make sure you also have the Ruby header files installed such as those provided by the [ruby-dev][] package on Debian and Ubuntu.
12
18
 
@@ -15,7 +21,9 @@ You can then install the library via RubyGems with `gem install re2` or `gem ins
15
21
  Documentation
16
22
  -------------
17
23
 
18
- Full documentation automatically generated from the latest version is available at <http://rdoc.info/projects/mudge/re2> and <http://yardoc.org/docs/mudge-re2/>.
24
+ Full documentation automatically generated from the latest version is available at <http://rubydoc.info/github/mudge/re2>.
25
+
26
+ Bear in mind that re2's regular expression syntax differs from PCRE, see the [official syntax page][] for more details.
19
27
 
20
28
  Usage
21
29
  -----
@@ -39,20 +47,33 @@ You can use re2 as a mostly drop-in replacement for Ruby's own [Regexp][] and [M
39
47
  > r.match("bob")
40
48
  => nil
41
49
 
50
+ As of 0.3.0, you can use named groups:
51
+
52
+ > r = RE2::Regexp.compile('(?P<name>\w+) (?P<age>\d+)')
53
+ => #<RE2::Regexp /(?P<name>\w+) (?P<age>\d+)/>
54
+ > m = r.match("Bob 40")
55
+ => #<RE2::MatchData "Bob 40" 1:"Bob" 2:"40">
56
+ > m[:name]
57
+ => "Bob"
58
+ > m["age"]
59
+ => "40"
60
+
42
61
  Features
43
62
  --------
44
63
 
45
64
  * Pre-compiling regular expressions with [`RE2::Regexp.new(re)`](http://code.google.com/p/re2/source/browse/re2/re2.h#96), `RE2::Regexp.compile(re)` or `RE2(re)` (including specifying options, e.g. `RE2::Regexp.new("pattern", :case_sensitive => false)`
46
65
 
47
- * Extracting matches with `re2.match(text)` (and an exact number of matches with `re2.match(text, number_of_matches)` such as `re2.match("123-234", 2)`)
66
+ * Extracting matches with `re2.match(text)` (and an exact number of matches with `re2.match(text, number_of_matches)` such as `re2.match("123-234", 2)`)
67
+
68
+ * Extracting matches by name (both with strings and symbols)
48
69
 
49
- * Checking for matches with `re2 =~ text`, `re2 === text` (for use in `case` statements) and `re2 !~ text`
70
+ * Checking for matches with `re2 =~ text`, `re2 === text` (for use in `case` statements) and `re2 !~ text`
50
71
 
51
- * Checking regular expression compilation with `re2.ok?`, `re2.error` and `re2.error_arg`
72
+ * Checking regular expression compilation with `re2.ok?`, `re2.error` and `re2.error_arg`
52
73
 
53
- * Checking regular expression "cost" with `re2.program_size`
74
+ * Checking regular expression "cost" with `re2.program_size`
54
75
 
55
- * Checking the options for an expression with `re2.options` or individually with `re2.case_sensitive?`
76
+ * Checking the options for an expression with `re2.options` or individually with `re2.case_sensitive?`
56
77
 
57
78
  * Performing in-place replacement with [`RE2::Replace(str, pattern, replace)`](http://code.google.com/p/re2/source/browse/re2/re2.h#335)
58
79
 
@@ -71,3 +92,6 @@ All feedback should go to the mailing list: <mailto:ruby.re2@librelist.com>
71
92
  [build-essential]: http://packages.debian.org/build-essential
72
93
  [Regexp]: http://ruby-doc.org/core/classes/Regexp.html
73
94
  [MatchData]: http://ruby-doc.org/core/classes/MatchData.html
95
+ [Homebrew]: http://mxcl.github.com/homebrew
96
+ [libre2-dev]: http://packages.debian.org/search?keywords=libre2-dev
97
+ [official syntax page]: http://code.google.com/p/re2/wiki/Syntax
@@ -12,6 +12,33 @@ $CFLAGS << " -Wall -Wextra -funroll-loops"
12
12
 
13
13
  have_library("stdc++")
14
14
  if have_library("re2")
15
+
16
+ # Determine which version of re2 the user has installed.
17
+ # Revision d9f8806c004d added an `endpos` argument to the
18
+ # generic Match() function.
19
+ #
20
+ # To test for this, try to compile a simple program that uses
21
+ # the newer form of Match() and set a flag if it is successful.
22
+ checking_for("RE2::Match() with endpos argument") do
23
+ test_re2_match_signature = <<SRC
24
+ #include <re2/re2.h>
25
+
26
+ int main() {
27
+ RE2 pattern("test");
28
+ re2::StringPiece *match;
29
+ pattern.Match("test", 0, 0, RE2::UNANCHORED, match, 0);
30
+
31
+ return 0;
32
+ }
33
+ SRC
34
+
35
+ # Pass -x c++ to force gcc to compile the test program
36
+ # as C++ (as it will end in .c by default).
37
+ if try_compile(test_re2_match_signature, "-x c++")
38
+ $defs.push("-DHAVE_ENDPOS_ARGUMENT")
39
+ end
40
+ end
41
+
15
42
  create_makefile("re2")
16
43
  else
17
44
  abort "You must have re2 installed and specified with --with-re2-dir, please see http://code.google.com/p/re2/wiki/Install"
@@ -7,6 +7,8 @@
7
7
  */
8
8
 
9
9
  #include <re2/re2.h>
10
+ #include <string>
11
+ using namespace std;
10
12
 
11
13
  extern "C" {
12
14
 
@@ -30,7 +32,7 @@ extern "C" {
30
32
  typedef struct {
31
33
  re2::StringPiece *matches;
32
34
  int number_of_matches;
33
- VALUE regexp, string;
35
+ VALUE regexp, text;
34
36
  } re2_matchdata;
35
37
 
36
38
  VALUE re2_mRE2, re2_cRegexp, re2_cMatchData;
@@ -43,7 +45,7 @@ extern "C" {
43
45
  void re2_matchdata_mark(re2_matchdata* self)
44
46
  {
45
47
  rb_gc_mark(self->regexp);
46
- rb_gc_mark(self->string);
48
+ rb_gc_mark(self->text);
47
49
  }
48
50
 
49
51
  void re2_matchdata_free(re2_matchdata* self)
@@ -84,7 +86,7 @@ extern "C" {
84
86
  re2_matchdata *m;
85
87
  Data_Get_Struct(self, re2_matchdata, m);
86
88
 
87
- return m->string;
89
+ return m->text;
88
90
  }
89
91
 
90
92
  /*
@@ -141,13 +143,16 @@ extern "C" {
141
143
  {
142
144
  int i;
143
145
  re2_matchdata *m;
146
+ re2::StringPiece match;
147
+
144
148
  Data_Get_Struct(self, re2_matchdata, m);
145
149
  VALUE array = rb_ary_new2(m->number_of_matches);
146
150
  for (i = 0; i < m->number_of_matches; i++) {
147
151
  if (m->matches[i].empty()) {
148
152
  rb_ary_push(array, Qnil);
149
153
  } else {
150
- rb_ary_push(array, rb_str_new(m->matches[i].data(), m->matches[i].size()));
154
+ match = m->matches[i];
155
+ rb_ary_push(array, rb_str_new(match.data(), match.size()));
151
156
  }
152
157
  }
153
158
  return array;
@@ -157,17 +162,42 @@ extern "C" {
157
162
  re2_matchdata_nth_match(int nth, VALUE self)
158
163
  {
159
164
  re2_matchdata *m;
165
+ re2::StringPiece match;
166
+
160
167
  Data_Get_Struct(self, re2_matchdata, m);
168
+ match = m->matches[nth];
161
169
 
162
- if (nth >= m->number_of_matches || m->matches[nth].empty()) {
170
+ if (nth >= m->number_of_matches || match.empty()) {
163
171
  return Qnil;
164
172
  } else {
165
- return rb_str_new(m->matches[nth].data(), m->matches[nth].size());
173
+ return rb_str_new(match.data(), match.size());
174
+ }
175
+ }
176
+
177
+ static VALUE
178
+ re2_matchdata_named_match(const char* name, VALUE self)
179
+ {
180
+ int idx;
181
+ re2_matchdata *m;
182
+ re2_pattern *p;
183
+ map<string, int> groups;
184
+ string name_as_string(name);
185
+
186
+ Data_Get_Struct(self, re2_matchdata, m);
187
+ Data_Get_Struct(m->regexp, re2_pattern, p);
188
+
189
+ groups = p->pattern->NamedCapturingGroups();
190
+
191
+ if (groups.count(name_as_string) == 1) {
192
+ idx = groups[name_as_string];
193
+ return re2_matchdata_nth_match(idx, self);
194
+ } else {
195
+ return Qnil;
166
196
  }
167
197
  }
168
198
 
169
199
  /*
170
- * Retrieve zero, one or more matches by index.
200
+ * Retrieve zero, one or more matches by index or name.
171
201
  *
172
202
  * @return [Array<String, nil>, String, Boolean]
173
203
  *
@@ -198,6 +228,16 @@ extern "C" {
198
228
  * @example
199
229
  * m = RE2('(\d+)').match("bob 123")
200
230
  * m[0..1] #=> "[123", "123"]
231
+ *
232
+ * @overload [](name)
233
+ * Access a particular match by name.
234
+ *
235
+ * @param [String, Symbol] name the name of the match to fetch
236
+ * @return [String, nil] the specific match
237
+ * @example
238
+ * m = RE2('(?P<number>\d+)').match("bob 123")
239
+ * m["number"] #=> "123"
240
+ * m[:number] #=> "123"
201
241
  */
202
242
  static VALUE
203
243
  re2_matchdata_aref(int argc, VALUE *argv, VALUE self)
@@ -205,7 +245,11 @@ extern "C" {
205
245
  VALUE idx, rest;
206
246
  rb_scan_args(argc, argv, "11", &idx, &rest);
207
247
 
208
- if (!NIL_P(rest) || !FIXNUM_P(idx) || FIX2INT(idx) < 0) {
248
+ if (TYPE(idx) == T_STRING) {
249
+ return re2_matchdata_named_match(StringValuePtr(idx), self);
250
+ } else if (TYPE(idx) == T_SYMBOL) {
251
+ return re2_matchdata_named_match(rb_id2name(SYM2ID(idx)), self);
252
+ } else if (!NIL_P(rest) || !FIXNUM_P(idx) || FIX2INT(idx) < 0) {
209
253
  return rb_ary_aref(argc, argv, re2_matchdata_to_a(self));
210
254
  } else {
211
255
  return re2_matchdata_nth_match(FIX2INT(idx), self);
@@ -391,9 +435,9 @@ extern "C" {
391
435
  re2_options.set_one_line(RTEST(one_line));
392
436
  }
393
437
 
394
- p->pattern = new (std::nothrow) RE2(StringValuePtr(pattern), re2_options);
438
+ p->pattern = new (nothrow) RE2(StringValuePtr(pattern), re2_options);
395
439
  } else {
396
- p->pattern = new (std::nothrow) RE2(StringValuePtr(pattern));
440
+ p->pattern = new (nothrow) RE2(StringValuePtr(pattern));
397
441
  }
398
442
 
399
443
  if (p->pattern == 0) {
@@ -773,6 +817,32 @@ extern "C" {
773
817
  return INT2FIX(p->pattern->NumberOfCapturingGroups());
774
818
  }
775
819
 
820
+ /*
821
+ * Returns a hash of names to capturing indices of groups.
822
+ *
823
+ * @return [Hash] a hash of names to capturing indices
824
+ */
825
+ static VALUE
826
+ re2_regexp_named_capturing_groups(VALUE self)
827
+ {
828
+ VALUE capturing_groups;
829
+ re2_pattern *p;
830
+ map<string, int> groups;
831
+ map<string, int>::iterator iterator;
832
+
833
+ Data_Get_Struct(self, re2_pattern, p);
834
+ groups = p->pattern->NamedCapturingGroups();
835
+ capturing_groups = rb_hash_new();
836
+
837
+ for (iterator = groups.begin(); iterator != groups.end(); iterator++) {
838
+ rb_hash_aset(capturing_groups,
839
+ rb_str_new(iterator->first.data(), iterator->first.size()),
840
+ INT2FIX(iterator->second));
841
+ }
842
+
843
+ return capturing_groups;
844
+ }
845
+
776
846
  /*
777
847
  * Match the pattern against the given +text+ and return either
778
848
  * a boolean (if no submatches are required) or a {RE2::MatchData}
@@ -836,10 +906,12 @@ extern "C" {
836
906
  n = p->pattern->NumberOfCapturingGroups();
837
907
  }
838
908
 
839
- re2::StringPiece text_as_string_piece(StringValuePtr(text));
840
-
841
909
  if (n == 0) {
842
- matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);
910
+ #if defined(HAVE_ENDPOS_ARGUMENT)
911
+ matched = p->pattern->Match(StringValuePtr(text), 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);
912
+ #else
913
+ matched = p->pattern->Match(StringValuePtr(text), 0, RE2::UNANCHORED, 0, 0);
914
+ #endif
843
915
  return BOOL2RUBY(matched);
844
916
  } else {
845
917
 
@@ -848,10 +920,10 @@ extern "C" {
848
920
 
849
921
  matchdata = rb_class_new_instance(0, 0, re2_cMatchData);
850
922
  Data_Get_Struct(matchdata, re2_matchdata, m);
851
- m->matches = new (std::nothrow) re2::StringPiece[n];
923
+ m->matches = new (nothrow) re2::StringPiece[n];
852
924
  m->regexp = self;
853
- m->string = rb_str_dup(text);
854
- rb_str_freeze(m->string);
925
+ m->text = rb_str_dup(text);
926
+ rb_str_freeze(m->text);
855
927
 
856
928
  if (m->matches == 0) {
857
929
  rb_raise(rb_eNoMemError, "not enough memory to allocate StringPieces for matches");
@@ -859,7 +931,11 @@ extern "C" {
859
931
 
860
932
  m->number_of_matches = n;
861
933
 
862
- matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, m->matches, n);
934
+ #if defined(HAVE_ENDPOS_ARGUMENT)
935
+ matched = p->pattern->Match(StringValuePtr(text), 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, m->matches, n);
936
+ #else
937
+ matched = p->pattern->Match(StringValuePtr(text), 0, RE2::UNANCHORED, m->matches, n);
938
+ #endif
863
939
 
864
940
  if (matched) {
865
941
  return matchdata;
@@ -912,19 +988,18 @@ extern "C" {
912
988
  re2_pattern *p;
913
989
 
914
990
  /* Convert all the inputs to be pumped into RE2::Replace. */
915
- std::string str_as_string(StringValuePtr(str));
916
- re2::StringPiece rewrite_as_string_piece(StringValuePtr(rewrite));
991
+ string str_as_string(StringValuePtr(str));
917
992
 
918
993
  /* Do the replacement. */
919
994
  if (rb_obj_is_kind_of(pattern, re2_cRegexp)) {
920
995
  Data_Get_Struct(pattern, re2_pattern, p);
921
- RE2::Replace(&str_as_string, *p->pattern, rewrite_as_string_piece);
996
+ RE2::Replace(&str_as_string, *p->pattern, StringValuePtr(rewrite));
922
997
  } else {
923
- RE2::Replace(&str_as_string, StringValuePtr(pattern), rewrite_as_string_piece);
998
+ RE2::Replace(&str_as_string, StringValuePtr(pattern), StringValuePtr(rewrite));
924
999
  }
925
1000
 
926
1001
  /* Save the replacement as a VALUE. */
927
- repl = rb_str_new(str_as_string.c_str(), str_as_string.length());
1002
+ repl = rb_str_new(str_as_string.data(), str_as_string.size());
928
1003
 
929
1004
  /* Replace the original string with the replacement. */
930
1005
  if (RSTRING_LEN(str) != RSTRING_LEN(repl)) {
@@ -961,20 +1036,19 @@ extern "C" {
961
1036
 
962
1037
  /* Convert all the inputs to be pumped into RE2::GlobalReplace. */
963
1038
  re2_pattern *p;
964
- std::string str_as_string(StringValuePtr(str));
965
- re2::StringPiece rewrite_as_string_piece(StringValuePtr(rewrite));
1039
+ string str_as_string(StringValuePtr(str));
966
1040
  VALUE repl;
967
1041
 
968
1042
  /* Do the replacement. */
969
1043
  if (rb_obj_is_kind_of(pattern, re2_cRegexp)) {
970
1044
  Data_Get_Struct(pattern, re2_pattern, p);
971
- RE2::GlobalReplace(&str_as_string, *p->pattern, rewrite_as_string_piece);
1045
+ RE2::GlobalReplace(&str_as_string, *p->pattern, StringValuePtr(rewrite));
972
1046
  } else {
973
- RE2::GlobalReplace(&str_as_string, StringValuePtr(pattern), rewrite_as_string_piece);
1047
+ RE2::GlobalReplace(&str_as_string, StringValuePtr(pattern), StringValuePtr(rewrite));
974
1048
  }
975
1049
 
976
1050
  /* Save the replacement as a VALUE. */
977
- repl = rb_str_new(str_as_string.c_str(), str_as_string.length());
1051
+ repl = rb_str_new(str_as_string.data(), str_as_string.size());
978
1052
 
979
1053
  /* Replace the original string with the replacement. */
980
1054
  if (RSTRING_LEN(str) != RSTRING_LEN(repl)) {
@@ -999,8 +1073,7 @@ extern "C" {
999
1073
  re2_QuoteMeta(VALUE self, VALUE unquoted)
1000
1074
  {
1001
1075
  UNUSED(self);
1002
- re2::StringPiece unquoted_as_string_piece(StringValuePtr(unquoted));
1003
- std::string quoted_string = RE2::QuoteMeta(unquoted_as_string_piece);
1076
+ string quoted_string = RE2::QuoteMeta(StringValuePtr(unquoted));
1004
1077
  return rb_str_new(quoted_string.data(), quoted_string.size());
1005
1078
  }
1006
1079
 
@@ -1030,6 +1103,7 @@ extern "C" {
1030
1103
  rb_define_method(re2_cRegexp, "program_size", RUBY_METHOD_FUNC(re2_regexp_program_size), 0);
1031
1104
  rb_define_method(re2_cRegexp, "options", RUBY_METHOD_FUNC(re2_regexp_options), 0);
1032
1105
  rb_define_method(re2_cRegexp, "number_of_capturing_groups", RUBY_METHOD_FUNC(re2_regexp_number_of_capturing_groups), 0);
1106
+ rb_define_method(re2_cRegexp, "named_capturing_groups", RUBY_METHOD_FUNC(re2_regexp_named_capturing_groups), 0);
1033
1107
  rb_define_method(re2_cRegexp, "match", RUBY_METHOD_FUNC(re2_regexp_match), -1);
1034
1108
  rb_define_method(re2_cRegexp, "match?", RUBY_METHOD_FUNC(re2_regexp_match_query), 1);
1035
1109
  rb_define_method(re2_cRegexp, "=~", RUBY_METHOD_FUNC(re2_regexp_match_query), 1);
@@ -121,11 +121,44 @@ class RE2Test < Test::Unit::TestCase
121
121
  assert_equal 2, RE2('a((b)c)').number_of_capturing_groups
122
122
  end
123
123
 
124
+ def test_named_capturing_groups
125
+ assert_equal(1, RE2('(?P<bob>a)').named_capturing_groups["bob"])
126
+ assert_equal(1, RE2('(?P<bob>a)(o)(?P<rob>e)').named_capturing_groups["bob"])
127
+ assert_equal(3, RE2('(?P<bob>a)(o)(?P<rob>e)').named_capturing_groups["rob"])
128
+ end
129
+
124
130
  def test_matching_all_subpatterns
125
131
  assert_equal ["woo", "o", "o"], RE2('w(o)(o)').match('woo').to_a
126
132
  assert_equal ["ab", nil, "a", "b"], RE2('(\d?)(a)(b)').match('ab').to_a
127
133
  end
128
134
 
135
+ def test_fetching_matchdata_out_of_range
136
+ matchdata = RE2('(\d+)').match('bob 123')
137
+ assert_nil matchdata[2]
138
+ assert_nil matchdata[3]
139
+ end
140
+
141
+ def test_accessing_matches_by_name
142
+ matchdata = RE2('(?P<numbers>\d+)').match("bob 123")
143
+ assert_equal "123", matchdata["numbers"]
144
+ assert_equal "123", matchdata[:numbers]
145
+ end
146
+
147
+ def test_accessing_matches_by_name_with_multiple_groups
148
+ matchdata = RE2('(?P<name>\w+)(\s*)(?P<numbers>\d+)').match("bob 123")
149
+ assert_equal "bob", matchdata["name"]
150
+ assert_equal "bob", matchdata[:name]
151
+ assert_equal " ", matchdata[2]
152
+ assert_equal "123", matchdata["numbers"]
153
+ assert_equal "123", matchdata[:numbers]
154
+ end
155
+
156
+ def test_accessing_matches_by_incorrect_names
157
+ matchdata = RE2('(?P<numbers>\d+)').match("bob 123")
158
+ assert_nil matchdata["missing"]
159
+ assert_nil matchdata[:missing]
160
+ end
161
+
129
162
  def test_matchdata
130
163
  r = RE2('(\d+)')
131
164
  text = "bob 123"
@@ -146,6 +179,7 @@ class RE2Test < Test::Unit::TestCase
146
179
  assert_equal "123", m.to_s
147
180
  assert_equal "123", m[0]
148
181
  assert_equal "123", m[1]
182
+ assert_nil m[4]
149
183
  assert_equal ["123"], m[0, 1]
150
184
  assert_equal ["123", "123"], m[0, 2]
151
185
  assert_equal ["123"], m[0...1]
metadata CHANGED
@@ -1,83 +1,64 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: re2
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 2
8
- - 0
9
- version: 0.2.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Paul Mucur
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-04-11 00:00:00 +01:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-02-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rake-compiler
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70320711075760 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :development
32
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: *70320711075760
33
25
  description: Ruby bindings to re2, "an efficient, principled regular expression library".
34
26
  email: ruby.re2@librelist.com
35
27
  executables: []
36
-
37
- extensions:
28
+ extensions:
38
29
  - ext/re2/extconf.rb
39
30
  extra_rdoc_files: []
40
-
41
- files:
31
+ files:
42
32
  - ext/re2/extconf.rb
43
33
  - ext/re2/re2.cc
44
34
  - LICENSE.txt
45
35
  - README.md
46
36
  - Rakefile
47
37
  - test/re2_test.rb
48
- - test/leak.rb
49
- has_rdoc: true
50
38
  homepage: http://github.com/mudge/re2
51
39
  licenses: []
52
-
53
40
  post_install_message:
54
41
  rdoc_options: []
55
-
56
- require_paths:
42
+ require_paths:
57
43
  - lib
58
- required_ruby_version: !ruby/object:Gem::Requirement
44
+ required_ruby_version: !ruby/object:Gem::Requirement
59
45
  none: false
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- segments:
64
- - 0
65
- version: "0"
66
- required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
51
  none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- segments:
72
- - 0
73
- version: "0"
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
74
56
  requirements: []
75
-
76
57
  rubyforge_project:
77
- rubygems_version: 1.3.7
58
+ rubygems_version: 1.8.11
78
59
  signing_key:
79
60
  specification_version: 3
80
61
  summary: Ruby bindings to re2.
81
- test_files:
62
+ test_files:
82
63
  - test/re2_test.rb
83
- - test/leak.rb
64
+ has_rdoc:
@@ -1,32 +0,0 @@
1
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- require 're2'
3
-
4
- loops = if ENV["LOOPS"]
5
- ENV["LOOPS"].to_i
6
- else
7
- 150
8
- end
9
-
10
- puts "Looping #{loops} times..."
11
-
12
- loops.times do
13
- r = RE2::Regexp.new('woo(oo)(o+)(\d*)')
14
- r.ok?
15
- r.match('wooo')
16
- r.match('wooo', 0)
17
- r.match('wooo', 1)
18
- r.match('wooo', 2)
19
- r =~ 'woooo'
20
- r =~ 'bob'
21
- RE2::Replace("woo", "woo", "bob")
22
- RE2::GlobalReplace("woo", "woo", "bob")
23
- m = r.match('woooooo1234')
24
- m[0]
25
- m[1]
26
- m[0,2]
27
- m[1..-1]
28
- m.string
29
- m.regexp
30
- m.inspect
31
- sleep 0.1
32
- end