Class: StringScanner (Ruby 2.3.2)
Description: Class : StringScanner - Ruby 2.3.2

- Home
- Core 2.3.2
- Std-lib 2.3.2
- Downloads

Support for the Ruby 2.3 series has ended. See here for reference.

### Home Classes Methods

### In Files

- strscan/strscan.c

### Parent

Object

### Namespace

- CLASS StringScanner::Error

### Methods

- ::must_C_version
- ::new
- #<<
- #[]
- #beginning_of_line?
- #charpos
- #check
- #check_until
- #clear
- #concat
- #empty?
- #eos?
- #exist?
- #get_byte
- #getbyte
- #getch
- #inspect
- #match?
- #matched
- #matched?
- #matched_size
- #peek
- #peep
- #pointer
- #pointer=
- #pos
- #pos=
- #post_match
- #pre_match
- #reset
- #rest
- #rest?
- #rest_size
- #restsize
- #scan
- #scan_full
- #scan_until
- #search_full
- #skip
- #skip_until
- #string
- #string=
- #terminate
- #unscan

### Class/Module Index

Quicksearch

- StringScanner
- StringScanner::Error

No matching classes.

# StringScanner

StringScanner provides for lexical scanning operations on a String. Here is an example of its usage:

    s = StringScanner.new('This is an example string')
    s.eos?               # -> false

    p s.scan(/\w+/)      # -> "This"
    p s.scan(/\w+/)      # -> nil
    p s.scan(/\s+/)      # -> " "
    p s.scan(/\s+/)      # -> nil
    p s.scan(/\w+/)      # -> "is"
    s.eos?               # -> false

    p s.scan(/\s+/)      # -> " "
    p s.scan(/\w+/)      # -> "an"
    p s.scan(/\s+/)      # -> " "
    p s.scan(/\w+/)      # -> "example"
    p s.scan(/\s+/)      # -> " "
    p s.scan(/\w+/)      # -> "string"
    s.eos?               # -> true

    p s.scan(/\s+/)      # -> nil
    p s.scan(/\w+/)      # -> nil

Scanning a string means remembering the position of a scan pointer, which is just an index. The point of scanning is to move forward a bit at a time, so matches are sought after the scan pointer; usually immediately after it.

Given the string “test string”, here are the pertinent scan pointer positions:

      t e s t   s t r i n g
    0 1 2 ...             1
                          0

When you scan for a pattern (a regular expression), the match must occur at the character after the scan pointer. If you use scan_until, then the match can occur anywhere after the scan pointer. In both cases, the scan pointer moves just beyond the last character of the match, ready to scan again from the next character onwards. This is demonstrated by the example above.

## Method Categories¶ ↑

There are other methods besides the plain scanners. You can look ahead in the string without actually scanning. You can access the most recent match. You can modify the string being scanned, reset or terminate the scanner, find out or change the position of the scan pointer, skip ahead, and so on.

### Advancing the Scan Pointer¶ ↑

- getch

- get_byte

- scan

- scan_until

- skip

- skip_until

### Looking Ahead¶ ↑

- check

- check_until

- exist?

- match?

- peek

### Finding Where we Are¶ ↑

- beginning_of_line? (#bol?)

- eos?

- rest?

- rest_size

- pos

### Setting Where we Are¶ ↑

- reset

- terminate

- pos=

### Match Data¶ ↑

- matched

- matched?

- matched_size

- pre_match

- post_match

### Miscellaneous¶ ↑

- <<

- concat

- string

- string=

- unscan

There are aliases to several of the methods.

### Public Class Methods

must_C_version click to toggle source

This method is defined for backward compatibility.

                   static VALUE
    strscan_s_mustc(VALUE self)
    {
        return self;
    }

new(string, dup = false) click to toggle source

Creates a new StringScanner object to scan over the given `string`. `dup` argument is obsolete and not used now.

                   static VALUE
    strscan_initialize(int argc, VALUE *argv, VALUE self)
    {
        struct strscanner *p;
        VALUE str, need_dup;

        p = check_strscan(self);
        rb_scan_args(argc, argv, "11", &str, &need_dup);
        StringValue(str);
        p->str = str;

        return self;
    }

### Public Instance Methods

<<(str) click to toggle source

Appends `str` to the string being scanned. This method does not affect scan pointer.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.scan(/Fri /)
    s << " +1000 GMT"
    s.string            # -> "Fri Dec 12 1975 14:39 +1000 GMT"
    s.scan(/Dec/)       # -> "Dec"

                   static VALUE
    strscan_concat(VALUE self, VALUE str)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        StringValue(str);
        rb_str_append(p->str, str);
        return self;
    }

[](n) click to toggle source

Return the n-th subgroup in the most recent match.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.scan(/(\w+) (\w+) (\d+) /)       # -> "Fri Dec 12 "
    s[0]                               # -> "Fri Dec 12 "
    s[1]                               # -> "Fri"
    s[2]                               # -> "Dec"
    s[3]                               # -> "12"
    s.post_match                       # -> "1975 14:39"
    s.pre_match                        # -> ""

    s.reset
    s.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /)       # -> "Fri Dec 12 "
    s[0]                               # -> "Fri Dec 12 "
    s[1]                               # -> "Fri"
    s[2]                               # -> "Dec"
    s[3]                               # -> "12"
    s[:wday]                           # -> "Fri"
    s[:month]                          # -> "Dec"
    s[:day]                            # -> "12"
    s.post_match                       # -> "1975 14:39"
    s.pre_match                        # -> ""

                   static VALUE
    strscan_aref(VALUE self, VALUE idx)
    {
        const char *name;
        struct strscanner *p;
        long i;

        GET_SCANNER(self, p);
        if (! MATCHED_P(p))        return Qnil;

        switch (TYPE(idx)) {
            case T_SYMBOL:
                idx = rb_sym2str(idx);
                /* fall through */
            case T_STRING:
                RSTRING_GETMEM(idx, name, i);
                i = name_to_backref_number(&(p->regs), p->regex, name, name + i, rb_enc_get(idx));
                break;
            default:
                i = NUM2LONG(idx);
        }

        if (i < 0)
            i += p->regs.num_regs;
        if (i < 0)                 return Qnil;
        if (i >= p->regs.num_regs) return Qnil;
        if (p->regs.beg[i] == -1)  return Qnil;

        return extract_range(p, p->prev + p->regs.beg[i],
                                p->prev + p->regs.end[i]);
    }

beginning_of_line?() click to toggle source

Returns `true` iff the scan pointer is at the beginning of the line.

    s = StringScanner.new("test\ntest\n")
    s.bol?           # => true
    s.scan(/te/)
    s.bol?           # => false
    s.scan(/st\n/)
    s.bol?           # => true
    s.terminate
    s.bol?           # => true

                   static VALUE
    strscan_bol_p(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (CURPTR(p) > S_PEND(p)) return Qnil;
        if (p->curr == 0) return Qtrue;
        return (*(CURPTR(p) - 1) == '\n') ? Qtrue : Qfalse;
    }

charpos() click to toggle source

Returns the character position of the scan pointer. In the 'reset' position, this value is zero. In the 'terminated' position (i.e. the string is exhausted), this value is the size of the string.

In short, it's a 0-based index into the string.

    s = StringScanner.new("abcädeföghi")
    s.charpos           # -> 0
    s.scan_until(/ä/)   # -> "abcä"
    s.pos               # -> 5
    s.charpos           # -> 4

                   static VALUE
    strscan_get_charpos(VALUE self)
    {
        struct strscanner *p;
        VALUE substr;

        GET_SCANNER(self, p);

        substr = rb_funcall(p->str, id_byteslice, 2, INT2FIX(0), INT2NUM(p->curr));

        return rb_str_length(substr);
    }

check(pattern) click to toggle source

This returns the value that scan would return, without advancing the scan pointer. The match register is affected, though.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.check /Fri/               # -> "Fri"
    s.pos                       # -> 0
    s.matched                   # -> "Fri"
    s.check /12/                # -> nil
    s.matched                   # -> nil

Mnemonic: it “checks” to see whether a scan will return a value.

                   static VALUE
    strscan_check(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 0, 1, 1);
    }

check_until(pattern) click to toggle source

This returns the value that scan_until would return, without advancing the scan pointer. The match register is affected, though.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.check_until /12/          # -> "Fri Dec 12"
    s.pos                       # -> 0
    s.matched                   # -> 12

Mnemonic: it “checks” to see whether a scan_until will return a value.

                   static VALUE
    strscan_check_until(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 0, 1, 0);
    }

clear() click to toggle source

Equivalent to terminate. This method is obsolete; use terminate instead.

                   static VALUE
    strscan_clear(VALUE self)
    {
        rb_warning("StringScanner#clear is obsolete; use #terminate instead");
        return strscan_terminate(self);
    }

concat(str) click to toggle source

Appends `str` to the string being scanned. This method does not affect scan pointer.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.scan(/Fri /)
    s << " +1000 GMT"
    s.string            # -> "Fri Dec 12 1975 14:39 +1000 GMT"
    s.scan(/Dec/)       # -> "Dec"

                   static VALUE
    strscan_concat(VALUE self, VALUE str)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        StringValue(str);
        rb_str_append(p->str, str);
        return self;
    }

empty?() click to toggle source

Equivalent to eos?. This method is obsolete, use eos? instead.

                   static VALUE
    strscan_empty_p(VALUE self)
    {
        rb_warning("StringScanner#empty? is obsolete; use #eos? instead");
        return strscan_eos_p(self);
    }

eos?() click to toggle source

Returns `true` if the scan pointer is at the end of the string.

    s = StringScanner.new('test string')
    p s.eos?          # => false
    s.scan(/test/)
    p s.eos?          # => false
    s.terminate
    p s.eos?          # => true

                   static VALUE
    strscan_eos_p(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        return EOS_P(p) ? Qtrue : Qfalse;
    }

exist?(pattern) click to toggle source

Looks ahead to see if the `pattern` exists anywhere in the string, without advancing the scan pointer. This predicates whether a scan_until will return a value.

    s = StringScanner.new('test string')
    s.exist? /s/            # -> 3
    s.scan /test/           # -> "test"
    s.exist? /s/            # -> 2
    s.exist? /e/            # -> nil

                   static VALUE
    strscan_exist_p(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 0, 0, 0);
    }

get_byte() click to toggle source

Scans one byte and returns it. This method is not multibyte character sensitive. See also: getch.

    s = StringScanner.new('ab')
    s.get_byte         # => "a"
    s.get_byte         # => "b"
    s.get_byte         # => nil

    $KCODE = 'EUC'
    s = StringScanner.new("\244\242")
    s.get_byte         # => "\244"
    s.get_byte         # => "\242"
    s.get_byte         # => nil

                   static VALUE
    strscan_get_byte(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        CLEAR_MATCH_STATUS(p);
        if (EOS_P(p))
            return Qnil;

        p->prev = p->curr;
        p->curr++;
        MATCHED(p);
        adjust_registers_to_matched(p);
        return extract_range(p, p->prev + p->regs.beg[0],
                                p->prev + p->regs.end[0]);
    }

getbyte() click to toggle source

Equivalent to get_byte. This method is obsolete; use get_byte instead.

                   static VALUE
    strscan_getbyte(VALUE self)
    {
        rb_warning("StringScanner#getbyte is obsolete; use #get_byte instead");
        return strscan_get_byte(self);
    }

getch() click to toggle source

Scans one character and returns it. This method is multibyte character sensitive.

    s = StringScanner.new("ab")
    s.getch           # => "a"
    s.getch           # => "b"
    s.getch           # => nil

    $KCODE = 'EUC'
    s = StringScanner.new("\244\242")
    s.getch           # => "\244\242"   # Japanese hira-kana "A" in EUC-JP
    s.getch           # => nil

                   static VALUE
    strscan_getch(VALUE self)
    {
        struct strscanner *p;
        long len;

        GET_SCANNER(self, p);
        CLEAR_MATCH_STATUS(p);
        if (EOS_P(p))
            return Qnil;

        len = rb_enc_mbclen(CURPTR(p), S_PEND(p), rb_enc_get(p->str));
        len = minl(len, S_RESTLEN(p));
        p->prev = p->curr;
        p->curr += len;
        MATCHED(p);
        adjust_registers_to_matched(p);
        return extract_range(p, p->prev + p->regs.beg[0],
                                p->prev + p->regs.end[0]);
    }

inspect() click to toggle source

Returns a string that represents the StringScanner object, showing:

- the current position

- the size of the string

- the characters surrounding the scan pointer

  s = ::new(“Fri Dec 12 1975 14:39”) s.inspect # -> '#<StringScanner 0/21 @ “Fri D…”>' s.scan_until /12/ # -> “Fri Dec 12” s.inspect # -> '#<StringScanner 10/21 “…ec 12” @ “ 1975…”>'

                   static VALUE
    strscan_inspect(VALUE self)
    {
        struct strscanner *p;
        VALUE a, b;

        p = check_strscan(self);
        if (NIL_P(p->str)) {
            a = rb_sprintf("#<%"PRIsVALUE" (uninitialized)>", rb_obj_class(self));
            return infect(a, p);
        }
        if (EOS_P(p)) {
            a = rb_sprintf("#<%"PRIsVALUE" fin>", rb_obj_class(self));
            return infect(a, p);
        }
        if (p->curr == 0) {
            b = inspect2(p);
            a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld @ %"PRIsVALUE">",
                           rb_obj_class(self),
                           p->curr, S_LEN(p),
                           b);
            return infect(a, p);
        }
        a = inspect1(p);
        b = inspect2(p);
        a = rb_sprintf("#<%"PRIsVALUE" %ld/%ld %"PRIsVALUE" @ %"PRIsVALUE">",
                       rb_obj_class(self),
                       p->curr, S_LEN(p),
                       a, b);
        return infect(a, p);
    }

match?(pattern) click to toggle source

Tests whether the given `pattern` is matched from the current scan pointer. Returns the length of the match, or `nil`. The scan pointer is not advanced.

    s = StringScanner.new('test string')
    p s.match?(/\w+/)   # -> 4
    p s.match?(/\w+/)   # -> 4
    p s.match?(/\s+/)   # -> nil

                   static VALUE
    strscan_match_p(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 0, 0, 1);
    }

matched() click to toggle source

Returns the last matched string.

    s = StringScanner.new('test string')
    s.match?(/\w+/)     # -> 4
    s.matched           # -> "test"

                   static VALUE
    strscan_matched(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (! MATCHED_P(p)) return Qnil;
        return extract_range(p, p->prev + p->regs.beg[0],
                                p->prev + p->regs.end[0]);
    }

matched?() click to toggle source

Returns `true` iff the last match was successful.

    s = StringScanner.new('test string')
    s.match?(/\w+/)     # => 4
    s.matched?          # => true
    s.match?(/\d+/)     # => nil
    s.matched?          # => false

                   static VALUE
    strscan_matched_p(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        return MATCHED_P(p) ? Qtrue : Qfalse;
    }

matched_size() click to toggle source

Returns the size of the most recent match (see matched), or `nil` if there was no recent match.

    s = StringScanner.new('test string')
    s.check /\w+/           # -> "test"
    s.matched_size          # -> 4
    s.check /\d+/           # -> nil
    s.matched_size          # -> nil

                   static VALUE
    strscan_matched_size(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (! MATCHED_P(p)) return Qnil;
        return INT2NUM(p->regs.end[0] - p->regs.beg[0]);
    }

peek(len) click to toggle source

Extracts a string corresponding to `string[pos,len]`, without advancing the scan pointer.

    s = StringScanner.new('test string')
    s.peek(7)          # => "test st"
    s.peek(7)          # => "test st"

                   static VALUE
    strscan_peek(VALUE self, VALUE vlen)
    {
        struct strscanner *p;
        long len;

        GET_SCANNER(self, p);

        len = NUM2LONG(vlen);
        if (EOS_P(p))
            return infect(str_new(p, "", 0), p);

        len = minl(len, S_RESTLEN(p));
        return extract_beg_len(p, p->curr, len);
    }

peep(p1) click to toggle source

Equivalent to peek. This method is obsolete; use peek instead.

                   static VALUE
    strscan_peep(VALUE self, VALUE vlen)
    {
        rb_warning("StringScanner#peep is obsolete; use #peek instead");
        return strscan_peek(self, vlen);
    }

pointer() click to toggle source

Returns the byte position of the scan pointer. In the 'reset' position, this value is zero. In the 'terminated' position (i.e. the string is exhausted), this value is the bytesize of the string.

In short, it's a 0-based index into bytes of the string.

    s = StringScanner.new('test string')
    s.pos               # -> 0
    s.scan_until /str/  # -> "test str"
    s.pos               # -> 8
    s.terminate         # -> #<StringScanner fin>
    s.pos               # -> 11

                   static VALUE
    strscan_get_pos(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        return INT2FIX(p->curr);
    }

pos=(n) click to toggle source

Set the byte position of the scan pointer.

    s = StringScanner.new('test string')
    s.pos = 7            # -> 7
    s.rest               # -> "ring"

                   static VALUE
    strscan_set_pos(VALUE self, VALUE v)
    {
        struct strscanner *p;
        long i;

        GET_SCANNER(self, p);
        i = NUM2INT(v);
        if (i < 0) i += S_LEN(p);
        if (i < 0) rb_raise(rb_eRangeError, "index out of range");
        if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
        p->curr = i;
        return INT2NUM(i);
    }

pos() click to toggle source

Returns the byte position of the scan pointer. In the 'reset' position, this value is zero. In the 'terminated' position (i.e. the string is exhausted), this value is the bytesize of the string.

In short, it's a 0-based index into bytes of the string.

    s = StringScanner.new('test string')
    s.pos               # -> 0
    s.scan_until /str/  # -> "test str"
    s.pos               # -> 8
    s.terminate         # -> #<StringScanner fin>
    s.pos               # -> 11

                   static VALUE
    strscan_get_pos(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        return INT2FIX(p->curr);
    }

pos=(n) click to toggle source

Set the byte position of the scan pointer.

    s = StringScanner.new('test string')
    s.pos = 7            # -> 7
    s.rest               # -> "ring"

                   static VALUE
    strscan_set_pos(VALUE self, VALUE v)
    {
        struct strscanner *p;
        long i;

        GET_SCANNER(self, p);
        i = NUM2INT(v);
        if (i < 0) i += S_LEN(p);
        if (i < 0) rb_raise(rb_eRangeError, "index out of range");
        if (i > S_LEN(p)) rb_raise(rb_eRangeError, "index out of range");
        p->curr = i;
        return INT2NUM(i);
    }

post_match() click to toggle source

Return the post-match (in the regular expression sense) of the last scan.

    s = StringScanner.new('test string')
    s.scan(/\w+/)           # -> "test"
    s.scan(/\s+/)           # -> " "
    s.pre_match             # -> "test"
    s.post_match            # -> "string"

                   static VALUE
    strscan_post_match(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (! MATCHED_P(p)) return Qnil;
        return extract_range(p, p->prev + p->regs.end[0], S_LEN(p));
    }

pre_match() click to toggle source

Return the pre-match (in the regular expression sense) of the last scan.

    s = StringScanner.new('test string')
    s.scan(/\w+/)           # -> "test"
    s.scan(/\s+/)           # -> " "
    s.pre_match             # -> "test"
    s.post_match            # -> "string"

                   static VALUE
    strscan_pre_match(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (! MATCHED_P(p)) return Qnil;
        return extract_range(p, 0, p->prev + p->regs.beg[0]);
    }

reset() click to toggle source

Reset the scan pointer (index 0) and clear matching data.

                   static VALUE
    strscan_reset(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        p->curr = 0;
        CLEAR_MATCH_STATUS(p);
        return self;
    }

rest() click to toggle source

Returns the “rest” of the string (i.e. everything after the scan pointer). If there is no more data (eos? = true), it returns `""`.

                   static VALUE
    strscan_rest(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (EOS_P(p)) {
            return infect(str_new(p, "", 0), p);
        }
        return extract_range(p, p->curr, S_LEN(p));
    }

rest?() click to toggle source

Returns true iff there is more data in the string. See eos?. This method is obsolete; use eos? instead.

    s = StringScanner.new('test string')
    s.eos?              # These two
    s.rest?             # are opposites.

                   static VALUE
    strscan_rest_p(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        return EOS_P(p) ? Qfalse : Qtrue;
    }

rest_size() click to toggle source

`s.rest_size` is equivalent to `s.rest.size`.

                   static VALUE
    strscan_rest_size(VALUE self)
    {
        struct strscanner *p;
        long i;

        GET_SCANNER(self, p);
        if (EOS_P(p)) {
            return INT2FIX(0);
        }
        i = S_RESTLEN(p);
        return INT2FIX(i);
    }

restsize() click to toggle source

`s.restsize` is equivalent to `s.rest_size`. This method is obsolete; use rest_size instead.

                   static VALUE
    strscan_restsize(VALUE self)
    {
        rb_warning("StringScanner#restsize is obsolete; use #rest_size instead");
        return strscan_rest_size(self);
    }

scan(pattern) => String click to toggle source

Tries to match with `pattern` at the current position. If there's a match, the scanner advances the “scan pointer” and returns the matched string. Otherwise, the scanner returns `nil`.

    s = StringScanner.new('test string')
    p s.scan(/\w+/)   # -> "test"
    p s.scan(/\w+/)   # -> nil
    p s.scan(/\s+/)   # -> " "
    p s.scan(/\w+/)   # -> "string"
    p s.scan(/./)     # -> nil

                   static VALUE
    strscan_scan(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 1, 1, 1);
    }

scan_full(pattern, advance_pointer_p, return_string_p) click to toggle source

Tests whether the given `pattern` is matched from the current scan pointer. Advances the scan pointer if `advance_pointer_p` is true. Returns the matched string if `return_string_p` is true. The match register is affected.

“full” means “#scan with full parameters”.

                   static VALUE
    strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)
    {
        return strscan_do_scan(self, re, RTEST(s), RTEST(f), 1);
    }

scan_until(pattern) click to toggle source

Scans the string until the `pattern` is matched. Returns the substring up to and including the end of the match, advancing the scan pointer to that location. If there is no match, `nil` is returned.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.scan_until(/1/)        # -> "Fri Dec 1"
    s.pre_match              # -> "Fri Dec "
    s.scan_until(/XYZ/)      # -> nil

                   static VALUE
    strscan_scan_until(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 1, 1, 0);
    }

search_full(pattern, advance_pointer_p, return_string_p) click to toggle source

Scans the string until the `pattern` is matched. Advances the scan pointer if `advance_pointer_p`, otherwise not. Returns the matched string if `return_string_p` is true, otherwise returns the number of bytes advanced. This method does affect the match register.

                   static VALUE
    strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f)
    {
        return strscan_do_scan(self, re, RTEST(s), RTEST(f), 0);
    }

skip(pattern) click to toggle source

Attempts to skip over the given `pattern` beginning with the scan pointer. If it matches, the scan pointer is advanced to the end of the match, and the length of the match is returned. Otherwise, `nil` is returned.

It's similar to scan, but without returning the matched string.

    s = StringScanner.new('test string')
    p s.skip(/\w+/)   # -> 4
    p s.skip(/\w+/)   # -> nil
    p s.skip(/\s+/)   # -> 1
    p s.skip(/\w+/)   # -> 6
    p s.skip(/./)     # -> nil

                   static VALUE
    strscan_skip(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 1, 0, 1);
    }

skip_until(pattern) click to toggle source

Advances the scan pointer until `pattern` is matched and consumed. Returns the number of bytes advanced, or `nil` if no match was found.

Look ahead to match `pattern`, and advance the scan pointer to the end of the match. Return the number of characters advanced, or `nil` if the match was unsuccessful.

It's similar to scan_until, but without returning the intervening string.

    s = StringScanner.new("Fri Dec 12 1975 14:39")
    s.skip_until /12/           # -> 10
    s                           #

                   static VALUE
    strscan_skip_until(VALUE self, VALUE re)
    {
        return strscan_do_scan(self, re, 1, 0, 0);
    }

string() click to toggle source

Returns the string being scanned.

                   static VALUE
    strscan_get_string(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        return p->str;
    }

string=(str) click to toggle source

Changes the string being scanned to `str` and resets the scanner. Returns `str`.

                   static VALUE
    strscan_set_string(VALUE self, VALUE str)
    {
        struct strscanner *p = check_strscan(self);

        StringValue(str);
        p->str = str;
        p->curr = 0;
        CLEAR_MATCH_STATUS(p);
        return str;
    }

terminate click to toggle source
clear

Set the scan pointer to the end of the string and clear matching data.

                   static VALUE
    strscan_terminate(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        p->curr = S_LEN(p);
        CLEAR_MATCH_STATUS(p);
        return self;
    }

unscan() click to toggle source

Set the scan pointer to the previous position. Only one previous position is remembered, and it changes with each scanning operation.

    s = StringScanner.new('test string')
    s.scan(/\w+/)        # => "test"
    s.unscan
    s.scan(/../)         # => "te"
    s.scan(/\d/)         # => nil
    s.unscan             # ScanError: unscan failed: previous match record not exist

                   static VALUE
    strscan_unscan(VALUE self)
    {
        struct strscanner *p;

        GET_SCANNER(self, p);
        if (! MATCHED_P(p))
            rb_raise(ScanError, "unscan failed: previous match record not exist");
        p->curr = p->prev;
        CLEAR_MATCH_STATUS(p);
        return self;
    }