re2 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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