Class: StringScanner
Relationships & Source Files | |
Namespace Children | |
Exceptions:
| |
Inherits: | Object |
Defined in: | ext/strscan/strscan.c, ext/strscan/strscan.c, ext/strscan/lib/strscan/strscan.rb |
Overview
:markup: markdown
Class Method Summary
-
.new(string, fixed_anchor: false) ⇒ string_scanner
constructor
private
:markup: markdown
- .must_C_version Internal use only
Instance Attribute Summary
-
#beginning_of_line? ⇒ Boolean
readonly
:markup: markdown
-
#eos? ⇒ Boolean
readonly
:markup: markdown
-
#fixed_anchor? ⇒ Boolean
readonly
:markup: markdown
-
#matched ⇒ matched_substring?
readonly
:markup: markdown
-
#matched? ⇒ Boolean
readonly
:markup: markdown
-
#pointer
rw
Alias for #pos.
-
#pos
(also: #pointer)
rw
:markup: markdown
-
#pos=(v)
(also: #pointer=)
rw
:markup: markdown
-
#rest ⇒ target_substring
readonly
:markup: markdown
-
#string ⇒ stored_string
rw
:markup: markdown
-
#string=(other_string) ⇒ other_string
rw
:markup: markdown
- #empty? ⇒ Boolean readonly Internal use only
- #rest? ⇒ Boolean readonly Internal use only
Instance Method Summary
-
#<<(more_string) ⇒ self
(also: #concat)
:markup: markdown
-
#[](specifier) ⇒ substring?
:markup: markdown
-
#captures ⇒ substring_array?
:markup: markdown
-
#charpos
:markup: markdown
-
#check(pattern) ⇒ matched_substring?
:markup: markdown
-
#check_until(pattern) ⇒ substring?
:markup: markdown
-
#concat(more_string) ⇒ self
Alias for #<<.
-
#exist?(pattern) ⇒ byte_offset?
:markup: markdown
-
#get_byte
:markup: markdown
-
#getch
:markup: markdown
-
#inspect ⇒ String
:markup: markdown
-
#match?(pattern) ⇒ updated_position?
:markup: markdown
-
#matched_size ⇒ substring_size?
:markup: markdown
-
#named_captures ⇒ Hash
:markup: markdown
-
#peek(length) ⇒ substring
:markup: markdown
-
#peek_byte
Peeks at the current byte and returns it as an integer.
-
#post_match ⇒ substring
:markup: markdown
-
#pre_match ⇒ substring
:markup: markdown
-
#reset ⇒ self
:markup: markdown
-
#rest_size ⇒ Integer
:markup: markdown
-
#scan(re)
:markup: markdown
-
#scan_byte ⇒ integer_byte
Scans one byte and returns it as an integer.
-
#scan_integer(base: 10)
If
base
isn’t provided or is10
, then it is equivalent to calling #scan with a[+-]?d+
pattern, and returns an Integer or nil. -
#scan_until(re)
:markup: markdown
-
#size ⇒ captures_count
:markup: markdown
-
#skip(re)
:markup: markdown
-
#skip_until(re)
:markup: markdown
-
#terminate
:markup: markdown
-
#unscan ⇒ self
:markup: markdown
-
#values_at(*specifiers) ⇒ array_of_captures?
:markup: markdown
-
#dup ⇒ shallow_copy
private
:markup: markdown
- #scan_base10_integer private
- #scan_base16_integer private
- #clear Internal use only
- #getbyte Internal use only
- #peep(vlen) Internal use only
- #restsize Internal use only
- #scan_full(re, s, f) Internal use only
- #search_full(re, s, f) Internal use only
Constructor Details
.new(string, fixed_anchor: false) ⇒ string_scanner
(private)
:markup: markdown
Returns a new StringScanner
object whose [stored string] is the given #string; sets the [fixed-anchor property]:
“‘ scanner = new
(’foobarbaz’) scanner.string # => “foobarbaz” scanner.fixed_anchor? # => false put_situation(scanner)
Situation:
pos: 0
charpos: 0
rest: “foobarbaz”
rest_size: 9
“‘
# File 'ext/strscan/strscan.c', line 247
static VALUE strscan_initialize(int argc, VALUE *argv, VALUE self) { struct strscanner *p; VALUE str, options; p = check_strscan(self); rb_scan_args(argc, argv, "11", &str, &options); options = rb_check_hash_type(options); if (!NIL_P(options)) { VALUE fixed_anchor; ID keyword_ids[1]; keyword_ids[0] = rb_intern("fixed_anchor"); rb_get_kwargs(options, keyword_ids, 0, 1, &fixed_anchor); if (fixed_anchor == Qundef) { p->fixed_anchor_p = false; } else { p->fixed_anchor_p = RTEST(fixed_anchor); } } else { p->fixed_anchor_p = false; } StringValue(str); p->str = str; return self; }
Class Method Details
.must_C_version
# File 'ext/strscan/strscan.c', line 325
static VALUE strscan_s_mustc(VALUE self) { return self; }
Instance Attribute Details
#beginning_of_line? ⇒ Boolean
(readonly)
:markup: markdown
Returns whether the [position] is at the beginning of a line; that is, at the beginning of the [stored string] or immediately after a newline:
scanner = StringScanner.new(MULTILINE_TEXT)
scanner.string
# => "Go placidly amid the noise and haste,\nand remember what peace there may be in silence.\n"
scanner.pos # => 0
scanner.beginning_of_line? # => true
scanner.scan_until(/,/) # => "Go placidly amid the noise and haste,"
scanner.beginning_of_line? # => false
scanner.scan(/\n/) # => "\n"
scanner.beginning_of_line? # => true
scanner.terminate
scanner.beginning_of_line? # => true
scanner.concat('x')
scanner.terminate
scanner.beginning_of_line? # => false
StringScanner#bol?
is an alias for beginning_of_line?
.
# File 'ext/strscan/strscan.c', line 1480
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; }
#empty? ⇒ Boolean
(readonly)
# File 'ext/strscan/strscan.c', line 1529
static VALUE strscan_empty_p(VALUE self) { rb_warning("StringScanner#empty? is obsolete; use #eos? instead"); return strscan_eos_p(self); }
#eos? ⇒ Boolean
(readonly)
# File 'ext/strscan/strscan.c', line 1511
static VALUE strscan_eos_p(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); return EOS_P(p) ? Qtrue : Qfalse; }
#fixed_anchor? ⇒ Boolean
(readonly)
:markup: markdown
Returns whether the [fixed-anchor property] is set.
# File 'ext/strscan/strscan.c', line 2183
static VALUE strscan_fixed_anchor_p(VALUE self) { struct strscanner *p; p = check_strscan(self); return p->fixed_anchor_p ? Qtrue : Qfalse; }
#matched ⇒ matched_substring
? (readonly)
:markup: markdown
Returns the matched substring from the most recent [match] attempt if it was successful, or nil
otherwise; see [Basic Matched Values]:
“‘ scanner = .new(’foobarbaz’) scanner.matched # => nil scanner.pos = 3 scanner.match?(/bar/) # => 3 scanner.matched # => “bar” scanner.match?(/nope/) # => nil scanner.matched # => nil “‘
# File 'ext/strscan/strscan.c', line 1613
static VALUE strscan_matched(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); if (! MATCHED_P(p)) return Qnil; return extract_range(p, adjust_register_position(p, p->regs.beg[0]), adjust_register_position(p, p->regs.end[0])); }
#matched? ⇒ Boolean
(readonly)
:markup: markdown
Returns true
of the most recent [match attempt] was successful, false
otherwise; see [Basic Matched Values]:
“‘ scanner = .new(’foobarbaz’) scanner.matched? # => false scanner.pos = 3 scanner.exist?(/baz/) # => 6 scanner.matched? # => true scanner.exist?(/nope/) # => nil scanner.matched? # => false “‘
# File 'ext/strscan/strscan.c', line 1581
static VALUE strscan_matched_p(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); return MATCHED_P(p) ? Qtrue : Qfalse; }
#pointer (rw)
Alias for #pos.
#pos (rw) Also known as: #pointer
:markup: markdown
# File 'ext/strscan/strscan.c', line 517
static VALUE strscan_get_pos(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); return INT2FIX(p->curr); }
#pos=(v) (rw) Also known as: #pointer=
:markup: markdown
# File 'ext/strscan/strscan.c', line 546
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 LONG2NUM(i); }
#rest ⇒ target_substring
(readonly)
:markup: markdown
Returns the ‘rest’ of the [stored string] (all after the current [position]), which is the [target substring]:
“‘ scanner = .new(’foobarbaz’) scanner.rest # => “foobarbaz” scanner.pos = 3 scanner.rest # => “barbaz” scanner.terminate scanner.rest # => “” “‘
# File 'ext/strscan/strscan.c', line 2004
static VALUE strscan_rest(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); if (EOS_P(p)) { return str_new(p, "", 0); } return extract_range(p, p->curr, S_LEN(p)); }
#rest? ⇒ Boolean
(readonly)
# File 'ext/strscan/strscan.c', line 1550
static VALUE strscan_rest_p(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); return EOS_P(p) ? Qfalse : Qtrue; }
#string ⇒ stored_string
(rw)
# File 'ext/strscan/strscan.c', line 416
static VALUE strscan_get_string(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); return p->str; }
#string=(other_string) ⇒ other_string
(rw)
:markup: markdown
Replaces the [stored string] with the given other_string
:
-
Sets both [positions] to zero.
-
Clears [match values].
-
Returns
other_string
.
“‘ scanner = .new(’foobar’) scanner.scan(/foo/) put_situation(scanner)
Situation:
pos: 3
charpos: 3
rest: “bar”
rest_size: 3
match_values_cleared?(scanner) # => false
scanner.string = ‘baz’ # => “baz” put_situation(scanner)
Situation:
pos: 0
charpos: 0
rest: “baz”
rest_size: 3
match_values_cleared?(scanner) # => true “‘
# File 'ext/strscan/strscan.c', line 460
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; }
Instance Method Details
#<<(more_string) ⇒ self
Also known as: #concat
:markup: markdown
-
Appends the given
more_string
to the [stored string]. -
Returns
self
. -
Does not affect the [positions] or [match values].
“‘ scanner = .new(’foo’) scanner.string # => “foo” scanner.terminate scanner.concat(‘barbaz’) # => #<StringScanner 3/9 “foo” @ “barba…”> scanner.string # => “foobarbaz” put_situation(scanner)
Situation:
pos: 3
charpos: 3
rest: “barbaz”
rest_size: 6
“‘
# File 'ext/strscan/strscan.c', line 501
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; }
#[](specifier) ⇒ substring
?
:markup: markdown
Returns a captured substring or nil
; see [Captured Match Values].
When there are captures:
“‘ scanner = .new(’Fri Dec 12 1975 14:39’) scanner.scan(/(?<wday>w+) (?<month>w+) (?<day>d+) /) “‘
-
specifier
zero: returns the entire matched substring:``` scanner[0] # => "Fri Dec 12 " scanner.pre_match # => "" scanner.post_match # => "1975 14:39" ```
-
specifier
positive integer. returns the ‘n`th capture, ornil
if out of range:``` scanner[1] # => "Fri" scanner[2] # => "Dec" scanner[3] # => "12" scanner[4] # => nil ```
-
specifier
negative integer. counts backward from the last subgroup:``` scanner[-1] # => "12" scanner[-4] # => "Fri Dec 12 " scanner[-5] # => nil ```
-
specifier
symbol or string. returns the named subgroup, ornil
if no such:``` scanner[:wday] # => "Fri" scanner['wday'] # => "Fri" scanner[:month] # => "Dec" scanner[:day] # => "12" scanner[:nope] # => nil ```
When there are no captures, only [0]
returns non-‘nil`:
“‘ scanner = .new(’foobarbaz’) scanner.exist?(/bar/) scanner # => “bar” scanner # => nil “‘
For a failed match, even [0]
returns nil
:
“‘ scanner.scan(/nope/) # => nil scanner # => nil scanner # => nil “`
# File 'ext/strscan/strscan.c', line 1749
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: if (!RTEST(p->regex)) return Qnil; 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, adjust_register_position(p, p->regs.beg[i]), adjust_register_position(p, p->regs.end[i])); }
#captures ⇒ substring_array
?
:markup: markdown
Returns the array of [captured match values] at indexes (1..)
if the most recent match attempt succeeded, or nil
otherwise:
“‘ scanner = .new(’Fri Dec 12 1975 14:39’) scanner.captures # => nil
scanner.exist?(/(?<wday>w+) (?<month>w+) (?<day>d+) /) scanner.captures # => [“Fri”, “Dec”, “12”] scanner.values_at(*0..4) # => [“Fri Dec 12 ”, “Fri”, “Dec”, “12”, nil]
scanner.exist?(/Fri/) scanner.captures # => []
scanner.scan(/nope/) scanner.captures # => nil “‘
# File 'ext/strscan/strscan.c', line 1843
static VALUE strscan_captures(VALUE self) { struct strscanner *p; int i, num_regs; VALUE new_ary; GET_SCANNER(self, p); if (! MATCHED_P(p)) return Qnil; num_regs = p->regs.num_regs; new_ary = rb_ary_new2(num_regs); for (i = 1; i < num_regs; i++) { VALUE str; if (p->regs.beg[i] == -1) str = Qnil; else str = extract_range(p, adjust_register_position(p, p->regs.beg[i]), adjust_register_position(p, p->regs.end[i])); rb_ary_push(new_ary, str); } return new_ary; }
#charpos
:markup: markdown
# File 'ext/strscan/strscan.c', line 531
static VALUE strscan_get_charpos(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); return LONG2NUM(rb_enc_strlen(S_PBEG(p), CURPTR(p), rb_enc_get(p->str))); }
#check(pattern) ⇒ matched_substring
?
:markup: markdown
Attempts to [match] the given pattern
at the beginning of the [target substring]; does not modify the [positions].
If the match succeeds:
-
Returns the matched substring.
-
Sets all [match values].
“‘ scanner = .new(’foobarbaz’) scanner.pos = 3 scanner.check(‘bar’) # => “bar” put_match_values(scanner)
Basic match values:
matched?: true
matched_size: 3
pre_match: “foo”
matched : “bar”
post_match: “baz”
Captured match values:
size: 1
captures: []
named_captures: {}
values_at: [“bar”, nil]
[]:
[0]: “bar”
[1]: nil
=> 0..1
put_situation(scanner)
Situation:
pos: 3
charpos: 3
rest: “barbaz”
rest_size: 6
“‘
If the match fails:
-
Returns
nil
. -
Clears all [match values].
“‘ scanner.check(/nope/) # => nil match_values_cleared?(scanner) # => true “`
# File 'ext/strscan/strscan.c', line 903
static VALUE strscan_check(VALUE self, VALUE re) { return strscan_do_scan(self, re, 0, 1, 1); }
#check_until(pattern) ⇒ substring
?
:markup: markdown
Attempts to [match] the given pattern
anywhere (at any [position]) in the [target substring]; does not modify the [positions].
If the match succeeds:
-
Sets all [match values].
-
Returns the matched substring, which extends from the current [position] to the end of the matched substring.
“‘ scanner = .new(’foobarbazbatbam’) scanner.pos = 6 scanner.check_until(/bat/) # => “bazbat” put_match_values(scanner)
Basic match values:
matched?: true
matched_size: 3
pre_match: “foobarbaz”
matched : “bat”
post_match: “bam”
Captured match values:
size: 1
captures: []
named_captures: {}
values_at: [“bat”, nil]
[]:
[0]: “bat”
[1]: nil
put_situation(scanner)
Situation:
pos: 6
charpos: 6
rest: “bazbatbam”
rest_size: 9
“‘
If the match fails:
-
Clears all [match values].
-
Returns
nil
.
“‘ scanner.check_until(/nope/) # => nil match_values_cleared?(scanner) # => true “`
# File 'ext/strscan/strscan.c', line 1076
static VALUE strscan_check_until(VALUE self, VALUE re) { return strscan_do_scan(self, re, 0, 1, 0); }
#clear
# File 'ext/strscan/strscan.c', line 392
static VALUE strscan_clear(VALUE self) { rb_warning("StringScanner#clear is obsolete; use #terminate instead"); return strscan_terminate(self); }
#<<(more_string) ⇒ self
#concat(more_string) ⇒ self
self
#concat(more_string) ⇒ self
Alias for #<<.
#exist?(pattern) ⇒ byte_offset
?
:markup: markdown
Attempts to [match] the given pattern
anywhere (at any [position]) n the [target substring]; does not modify the [positions].
If the match succeeds:
-
Returns a byte offset: the distance in bytes between the current [position] and the end of the matched substring.
-
Sets all [match values].
“‘ scanner = .new(’foobarbazbatbam’) scanner.pos = 6 scanner.exist?(/bat/) # => 6 put_match_values(scanner)
Basic match values:
matched?: true
matched_size: 3
pre_match: “foobarbaz”
matched : “bat”
post_match: “bam”
Captured match values:
size: 1
captures: []
named_captures: {}
values_at: [“bat”, nil]
[]:
[0]: “bat”
[1]: nil
put_situation(scanner)
Situation:
pos: 6
charpos: 6
rest: “bazbatbam”
rest_size: 9
“‘
If the match fails:
-
Returns
nil
. -
Clears all [match values].
“‘ scanner.exist?(/nope/) # => nil match_values_cleared?(scanner) # => true “`
# File 'ext/strscan/strscan.c', line 1002
static VALUE strscan_exist_p(VALUE self, VALUE re) { return strscan_do_scan(self, re, 0, 0, 0); }
#get_byte
:markup: markdown
# File 'ext/strscan/strscan.c', line 1197
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, adjust_register_position(p, p->regs.beg[0]), adjust_register_position(p, p->regs.end[0])); }
#getbyte
# File 'ext/strscan/strscan.c', line 1225
static VALUE strscan_getbyte(VALUE self) { rb_warning("StringScanner#getbyte is obsolete; use #get_byte instead"); return strscan_get_byte(self); }
#getch
:markup: markdown
# File 'ext/strscan/strscan.c', line 1124
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, adjust_register_position(p, p->regs.beg[0]), adjust_register_position(p, p->regs.end[0])); }
#dup ⇒ shallow_copy
(private)
:markup: markdown
Returns a shallow copy of self
; the [stored string] in the copy is the same string as in self
.
# File 'ext/strscan/strscan.c', line 293
static VALUE strscan_init_copy(VALUE vself, VALUE vorig) { struct strscanner *self, *orig; self = check_strscan(vself); orig = check_strscan(vorig); if (self != orig) { self->flags = orig->flags; self->str = orig->str; self->prev = orig->prev; self->curr = orig->curr; if (rb_reg_region_copy(&self->regs, &orig->regs)) rb_memerror(); RB_GC_GUARD(vorig); } return vself; }
#inspect ⇒ String
:markup: markdown
Returns a string representation of self
that may show:
-
The current [position].
-
The size (in bytes) of the [stored string].
-
The substring preceding the current position.
-
The substring following the current position (which is also the [target substring]).
“‘ scanner = .new(“Fri Dec 12 1975 14:39”) scanner.pos = 11 scanner.inspect # => “#<StringScanner 11/21 "…c 12 " @ "1975 …">” “`
If at beginning-of-string, item 4 above (following substring) is omitted:
“‘ scanner.reset scanner.inspect # => “#<StringScanner 0/21 @ "Fri D…">” “`
If at end-of-string, all items above are omitted:
“‘ scanner.terminate scanner.inspect # => “#<StringScanner fin>” “`
# File 'ext/strscan/strscan.c', line 2105
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 a; } if (EOS_P(p)) { a = rb_sprintf("#<%"PRIsVALUE" fin>", rb_obj_class(self)); return a; } 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 a; } 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 a; }
#match?(pattern) ⇒ updated_position
?
:markup: markdown
Attempts to [match] the given pattern
at the beginning of the [target substring]; does not modify the [positions].
If the match succeeds:
-
Sets [match values].
-
Returns the size in bytes of the matched substring.
“‘ scanner = .new(’foobarbaz’) scanner.pos = 3 scanner.match?(/bar/) => 3 put_match_values(scanner)
Basic match values:
matched?: true
matched_size: 3
pre_match: “foo”
matched : “bar”
post_match: “baz”
Captured match values:
size: 1
captures: []
named_captures: {}
values_at: [“bar”, nil]
[]:
[0]: “bar”
[1]: nil
put_situation(scanner)
Situation:
pos: 3
charpos: 3
rest: “barbaz”
rest_size: 6
“‘
If the match fails:
-
Clears match values.
-
Returns
nil
. -
Does not increment positions.
“‘ scanner.match?(/nope/) # => nil match_values_cleared?(scanner) # => true “`
# File 'ext/strscan/strscan.c', line 831
static VALUE strscan_match_p(VALUE self, VALUE re) { return strscan_do_scan(self, re, 0, 0, 1); }
#matched_size ⇒ substring_size
?
:markup: markdown
Returns the size (in bytes) of the matched substring from the most recent match [match attempt] if it was successful, or nil
otherwise; see [Basic Matched Values]:
“‘ scanner = .new(’foobarbaz’) scanner.matched_size # => nil
pos = 3 scanner.exist?(/baz/) # => 9 scanner.matched_size # => 3
scanner.exist?(/nope/) # => nil scanner.matched_size # => nil “‘
# File 'ext/strscan/strscan.c', line 1650
static VALUE strscan_matched_size(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); if (! MATCHED_P(p)) return Qnil; return LONG2NUM(p->regs.end[0] - p->regs.beg[0]); }
#named_captures ⇒ Hash
:markup: markdown
Returns the array of captured match values at indexes (1..) if the most recent match attempt succeeded, or nil otherwise; see [Captured Match Values]:
“‘ scanner = .new(’Fri Dec 12 1975 14:39’) scanner.named_captures # => {}
pattern = /(?<wday>w+) (?<month>w+) (?<day>d+) / scanner.match?(pattern) scanner.named_captures # => “month”=>“Dec”, “day”=>“12”
scanner.string = ‘nope’ scanner.match?(pattern) scanner.named_captures # => “month”=>nil, “day”=>nil
scanner.match?(/nosuch/) scanner.named_captures # => {} “‘
# File 'ext/strscan/strscan.c', line 2244
static VALUE strscan_named_captures(VALUE self) { struct strscanner *p; named_captures_data data; GET_SCANNER(self, p); data.self = self; data.captures = rb_hash_new(); if (!RB_NIL_P(p->regex)) { onig_foreach_name(RREGEXP_PTR(p->regex), named_captures_iter, &data); } return data.captures; }
#peek(length) ⇒ substring
:markup: markdown
Returns the substring ‘string[pos, length]`; does not update [match values] or [positions]:
“‘ scanner = .new(’foobarbaz’) scanner.pos = 3 scanner.peek(3) # => “bar” scanner.terminate scanner.peek(3) # => “” “‘
# File 'ext/strscan/strscan.c', line 1251
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 str_new(p, "", 0); len = minl(len, S_RESTLEN(p)); return extract_beg_len(p, p->curr, len); }
#peek_byte
Peeks at the current byte and returns it as an integer.
s = StringScanner.new('ab')
s.peek_byte # => 97
# File 'ext/strscan/strscan.c', line 1180
static VALUE strscan_peek_byte(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); if (EOS_P(p)) return Qnil; return INT2FIX((unsigned char)*CURPTR(p)); }
#peep(vlen)
# File 'ext/strscan/strscan.c', line 1276
static VALUE strscan_peep(VALUE self, VALUE vlen) { rb_warning("StringScanner#peep is obsolete; use #peek instead"); return strscan_peek(self, vlen); }
#post_match ⇒ substring
:markup: markdown
Returns the substring that follows the matched substring from the most recent match attempt if it was successful, or nil
otherwise; see [Basic Match Values]:
“‘ scanner = .new(’foobarbaz’) scanner.post_match # => nil
scanner.pos = 3 scanner.match?(/bar/) # => 3 scanner.post_match # => “baz”
scanner.match?(/nope/) # => nil scanner.post_match # => nil “‘
# File 'ext/strscan/strscan.c', line 1972
static VALUE strscan_post_match(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); if (! MATCHED_P(p)) return Qnil; return extract_range(p, adjust_register_position(p, p->regs.end[0]), S_LEN(p)); }
#pre_match ⇒ substring
:markup: markdown
Returns the substring that precedes the matched substring from the most recent match attempt if it was successful, or nil
otherwise; see [Basic Match Values]:
“‘ scanner = .new(’foobarbaz’) scanner.pre_match # => nil
scanner.pos = 3 scanner.exist?(/baz/) # => 6 scanner.pre_match # => “foobar” # Substring of entire string, not just target string.
scanner.exist?(/nope/) # => nil scanner.pre_match # => nil “‘
# File 'ext/strscan/strscan.c', line 1935
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, adjust_register_position(p, p->regs.beg[0])); }
#reset ⇒ self
:markup: markdown
Sets both [byte position] and [character position] to zero, and clears [match values]; returns self
:
“‘ scanner = .new(’foobarbaz’) scanner.exist?(/bar/) # => 6 scanner.reset # => #<StringScanner 0/9 @ “fooba…”> put_situation(scanner)
Situation:
pos: 0
charpos: 0
rest: “foobarbaz”
rest_size: 9
=> nil
match_values_cleared?(scanner) # => true “‘
# File 'ext/strscan/strscan.c', line 357
static VALUE strscan_reset(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); p->curr = 0; CLEAR_MATCH_STATUS(p); return self; }
#rest_size ⇒ Integer
:markup: markdown
Returns the size (in bytes) of the #rest of the [stored string]:
“‘ scanner = .new(’foobarbaz’) scanner.rest # => “foobarbaz” scanner.rest_size # => 9 scanner.pos = 3 scanner.rest # => “barbaz” scanner.rest_size # => 6 scanner.terminate scanner.rest # => “” scanner.rest_size # => 0 “‘
# File 'ext/strscan/strscan.c', line 2038
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
# File 'ext/strscan/strscan.c', line 2061
static VALUE strscan_restsize(VALUE self) { rb_warning("StringScanner#restsize is obsolete; use #rest_size instead"); return strscan_rest_size(self); }
#scan(re)
:markup: markdown
# File 'ext/strscan/strscan.c', line 769
static VALUE strscan_scan(VALUE self, VALUE re) { return strscan_do_scan(self, re, 1, 1, 1); }
#scan_base10_integer (private)
[ GitHub ]# File 'ext/strscan/strscan.c', line 1316
static VALUE strscan_scan_base10_integer(VALUE self) { char *ptr; long len = 0; struct strscanner *p; GET_SCANNER(self, p); CLEAR_MATCH_STATUS(p); strscan_must_ascii_compat(p->str); ptr = CURPTR(p); long remaining_len = S_RESTLEN(p); if (remaining_len <= 0) { return Qnil; } if (ptr[len] == '-' || ptr[len] == '+') { len++; } if (!rb_isdigit(ptr[len])) { return Qnil; } MATCHED(p); p->prev = p->curr; while (len < remaining_len && rb_isdigit(ptr[len])) { len++; } return strscan_parse_integer(p, 10, len); }
#scan_base16_integer (private)
[ GitHub ]# File 'ext/strscan/strscan.c', line 1354
static VALUE strscan_scan_base16_integer(VALUE self) { char *ptr; long len = 0; struct strscanner *p; GET_SCANNER(self, p); CLEAR_MATCH_STATUS(p); strscan_must_ascii_compat(p->str); ptr = CURPTR(p); long remaining_len = S_RESTLEN(p); if (remaining_len <= 0) { return Qnil; } if (ptr[len] == '-' || ptr[len] == '+') { len++; } if ((remaining_len >= (len + 2)) && ptr[len] == '0' && ptr[len + 1] == 'x') { len += 2; } if (len >= remaining_len || !rb_isxdigit(ptr[len])) { return Qnil; } MATCHED(p); p->prev = p->curr; while (len < remaining_len && rb_isxdigit(ptr[len])) { len++; } return strscan_parse_integer(p, 16, len); }
#scan_byte ⇒ integer_byte
Scans one byte and returns it as an integer. This method is not multibyte character sensitive. See also: #getch.
# File 'ext/strscan/strscan.c', line 1155
static VALUE strscan_scan_byte(VALUE self) { struct strscanner *p; VALUE byte; GET_SCANNER(self, p); CLEAR_MATCH_STATUS(p); if (EOS_P(p)) return Qnil; byte = INT2FIX((unsigned char)*CURPTR(p)); p->prev = p->curr; p->curr++; MATCHED(p); adjust_registers_to_matched(p); return byte; }
#scan_full(re, s, f)
# File 'ext/strscan/strscan.c', line 928
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_integer(base: 10)
If base
isn’t provided or is 10
, then it is equivalent to calling #scan with a [+-]?d+
pattern, and returns an Integer or nil.
If base
is 16
, then it is equivalent to calling #scan with a [+-]?(0x)?[0-9a-fA-F]+
pattern, and returns an Integer or nil.
The scanned string must be encoded with an ASCII compatible encoding, otherwise Encoding::CompatibilityError
will be raised.
# File 'ext/strscan/lib/strscan/strscan.rb', line 15
def scan_integer(base: 10) case base when 10 scan_base10_integer when 16 scan_base16_integer else raise ArgumentError, "Unsupported integer base: #{base.inspect}, expected 10 or 16" end end
#scan_until(re)
:markup: markdown
# File 'ext/strscan/strscan.c', line 939
static VALUE strscan_scan_until(VALUE self, VALUE re) { return strscan_do_scan(self, re, 1, 1, 0); }
#search_full(re, s, f)
# File 'ext/strscan/strscan.c', line 1101
static VALUE strscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f) { return strscan_do_scan(self, re, RTEST(s), RTEST(f), 0); }
#size ⇒ captures_count
:markup: markdown
Returns the count of captures if the most recent match attempt succeeded, nil
otherwise; see [Captures Match Values]:
“‘ scanner = .new(’Fri Dec 12 1975 14:39’) scanner.size # => nil
pattern = /(?<wday>w+) (?<month>w+) (?<day>d+) / scanner.match?(pattern) scanner.values_at(*0..scanner.size) # => [“Fri Dec 12 ”, “Fri”, “Dec”, “12”, nil] scanner.size # => 4
scanner.match?(/nope/) # => nil scanner.size # => nil “‘
# File 'ext/strscan/strscan.c', line 1807
static VALUE strscan_size(VALUE self) { struct strscanner *p; GET_SCANNER(self, p); if (! MATCHED_P(p)) return Qnil; return INT2FIX(p->regs.num_regs); }
#skip(re)
:markup: markdown
# File 'ext/strscan/strscan.c', line 842
static VALUE strscan_skip(VALUE self, VALUE re) { return strscan_do_scan(self, re, 1, 0, 1); }
#skip_until(re)
:markup: markdown
# File 'ext/strscan/strscan.c', line 1013
static VALUE strscan_skip_until(VALUE self, VALUE re) { return strscan_do_scan(self, re, 1, 0, 0); }
#terminate
:markup: markdown
# File 'ext/strscan/strscan.c', line 373
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 ⇒ self
:markup: markdown
Sets the [position] to its value previous to the recent successful
- match][17
-
attempt:
“‘ scanner = .new(’foobarbaz’) scanner.scan(/foo/) put_situation(scanner)
Situation:
pos: 3
charpos: 3
rest: “barbaz”
rest_size: 6
scanner.unscan
=> #<StringScanner 0/9 @ “fooba…”>
put_situation(scanner)
Situation:
pos: 0
charpos: 0
rest: “foobarbaz”
rest_size: 9
“‘
Raises an exception if match values are clear:
“‘ scanner.scan(/nope/) # => nil match_values_cleared?(scanner) # => true scanner.unscan # Raises ::StringScanner::Error
. “`
# File 'ext/strscan/strscan.c', line 1434
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; }
#values_at(*specifiers) ⇒ array_of_captures
?
:markup: markdown
Returns an array of captured substrings, or nil
of none.
For each specifier
, the returned substring is ‘[specifier]`; see #[].
“‘ scanner = .new(’Fri Dec 12 1975 14:39’) pattern = /(?<wday>w+) (?<month>w+) (?<day>d+) / scanner.match?(pattern) scanner.values_at(*0..3) # => [“Fri Dec 12 ”, “Fri”, “Dec”, “12”] scanner.values_at(*%i[wday month day]) # => [“Fri”, “Dec”, “12”] “‘
# File 'ext/strscan/strscan.c', line 1892
static VALUE strscan_values_at(int argc, VALUE *argv, VALUE self) { struct strscanner *p; long i; VALUE new_ary; GET_SCANNER(self, p); if (! MATCHED_P(p)) return Qnil; new_ary = rb_ary_new2(argc); for (i = 0; i<argc; i++) { rb_ary_push(new_ary, strscan_aref(self, argv[i])); } return new_ary; }