class RE2::Scanner

Public Instance Methods

each() { |matches| ... } click to toggle source
# File lib/re2/scanner.rb, line 5
def each
  if block_given?
    while matches = scan
      yield matches
    end
  else
    to_enum(:each)
  end
end
eof?() click to toggle source

Returns whether the scanner has consumed all input or not.

@return [Boolean] whether the scanner has consumed all input or not @example

c = RE2::Regexp.new('(\d+)').scan("foo")
c.eof? #=> true
static VALUE re2_scanner_eof(VALUE self) {
  re2_scanner *c;
  Data_Get_Struct(self, re2_scanner, c);

  return BOOL2RUBY(c->eof);
}
regexp() click to toggle source

Returns the {RE2::Regexp} used in the scanner.

@return [RE2::Regexp] the regexp used in the scanner @example

c = RE2::Regexp.new('(\d+)').scan("bob 123")
c.regexp    #=> #<RE2::Regexp /(\d+)/>
static VALUE re2_scanner_regexp(VALUE self) {
  re2_scanner *c;
  Data_Get_Struct(self, re2_scanner, c);

  return c->regexp;
}
rewind() click to toggle source

Rewind the scanner to the start of the string.

@example

s = RE2::Regexp.new('(\d+)').scan("1 2 3")
e = s.to_enum
e.scan #=> ["1"]
e.scan #=> ["2"]
s.rewind
e.scan #=> ["1"]
static VALUE re2_scanner_rewind(VALUE self) {
  re2_scanner *c;
  Data_Get_Struct(self, re2_scanner, c);

  c->input = new(nothrow) re2::StringPiece(StringValuePtr(c->text));
  c->eof = false;

  return self;
}
scan() click to toggle source

Scan the given text incrementally for matches, returning an array of matches on each subsequent call. Returns nil if no matches are found.

@return [Array<String>] the matches. @example

s = RE2::Regexp.new('(\w+)').scan("Foo bar baz")
s.scan #=> ["Foo"]
s.scan #=> ["bar"]
static VALUE re2_scanner_scan(VALUE self) {
  int i;
  size_t original_input_size, new_input_size;
  bool input_advanced;
  re2_pattern *p;
  re2_scanner *c;
  VALUE result;

  Data_Get_Struct(self, re2_scanner, c);
  Data_Get_Struct(c->regexp, re2_pattern, p);

  vector<RE2::Arg> argv(c->number_of_capturing_groups);
  vector<RE2::Arg*> args(c->number_of_capturing_groups);
  vector<string> matches(c->number_of_capturing_groups);

  if (c->eof) {
    return Qnil;
  }

  original_input_size = c->input->size();

  for (i = 0; i < c->number_of_capturing_groups; i++) {
    matches[i] = "";
    argv[i] = &matches[i];
    args[i] = &argv[i];
  }

  if (RE2::FindAndConsumeN(c->input, *p->pattern, &args[0],
        c->number_of_capturing_groups)) {
    result = rb_ary_new2(c->number_of_capturing_groups);
    new_input_size = c->input->size();
    input_advanced = new_input_size < original_input_size;

    for (i = 0; i < c->number_of_capturing_groups; i++) {
      if (matches[i].empty()) {
        rb_ary_push(result, Qnil);
      } else {
        rb_ary_push(result, ENCODED_STR_NEW(matches[i].data(),
              matches[i].size(),
              p->pattern->options().utf8() ? "UTF-8" : "ISO-8859-1"));
      }
    }

    /* Check whether we've exhausted the input yet. */
    c->eof = new_input_size == 0;

    /* If the match didn't advance the input, we need to do this ourselves. */
    if (!input_advanced && new_input_size > 0) {
      c->input->remove_prefix(1);
    }
  } else {
    result = Qnil;
  }

  return result;
}
string() click to toggle source

Returns the string passed into the scanner.

@return [String] the original string. @example

c = RE2::Regexp.new('(\d+)').scan("foo")
c.string #=> "foo"
static VALUE re2_scanner_string(VALUE self) {
  re2_scanner *c;
  Data_Get_Struct(self, re2_scanner, c);

  return c->text;
}