非常教程

Ruby 2.4参考手册

StringScanner

StringScanner

Parent:Object

StringScanner为字符串提供词法扫描操作。这是一个用法的例子:

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

扫描字符串意味着记住扫描指针的位置,这只是一个索引。扫描的重点是一次向前移动一点,所以在扫描指针之后寻找匹配。通常在它之后。

给定字符串“测试字符串”,这里是相关的扫描指针位置:

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

扫描模式(正则表达式)时,匹配必须发生在扫描指针后面的字符处。如果您使用scan_until,则匹配可能发生在扫描指针之后的任何位置。在这两种情况下,扫描指针移动刚刚超越本场比赛的最后一个字符,准备从下一个字符开始重新扫描。上面的例子证明了这一点。

方法类别

除了普通扫描仪之外,还有其他方法。您可以在没有实际扫描的情况下向前看。您可以访问最近的比赛。您可以修改正在扫描的字符串,重置或终止扫描仪,找出或更改扫描指针的位置,向前跳过,等等。

推进扫描指针

  • getch
  • get_byte
  • scan
  • scan_until
  • skip
  • skip_until

展望未来

  • check
  • check_until
  • exist?
  • match?
  • peekFinding Where we Are
  • beginning_of_line? (#bol?)
  • eos?
  • rest?
  • rest_size
  • pos

设置我们的位置

  • reset
  • terminate
  • pos=Match
  • matched
  • matched?
  • matched_size
  • pre_match
  • post_match

杂事

  • <<
  • concat
  • string
  • string=
  • unscan有几个方法的别名。公共类方法must_C_version显示源此方法是为向后兼容定义的。静态VALUE strscan_s_mustc(VALUE self){return self; } new(string,dup = false)显示源创建一个新的StringScanner对象来扫描给定的对象stringdup参数是过时的,并没有使用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; 回归自我; }公共实例方法<<(str)显示源追加str到被扫描的字符串。此方法不影响扫描指针。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); 回归自我; }显示源返回最近匹配的第n个子组.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” static VALUE strscan_aref(VALUE self,VALUE idx){const char * name; struct strscanner * p; 长我; GET_SCANNER(self,p); 如果(!MATCHED_P(p))返回Qnil; 开关(TYPE(idx)){case T_SYMBOL:idx = rb_sym2str(idx); / *落入* / case T_STRING:RSTRING_GETMEM(idx,name,i); i = name_to_backref_number(&(p-> regs),p-> regex,name,name + i,rb_enc_get(idx)); 打破; 默认值:i = NUM​​2LONG(idx); } if(i <0)i + = p-> regs.num_regs; 如果(i <0)返回Qnil; 如果(i> = p-> regs.num_regs)返回Qnil; 如果(p-> regs.beg [i] == -1)返回Qnil; 返回extract_range(p,p-> prev + p-> regs.beg [i],p-> prev + p-> regs.end [i]);true如果扫描指针位于该行的开始处。= StringScanner.new(“test \ ntest \ n”)s.bol?#=> true s.scan(/ te /)s.bol?#=>假s.scan(/ st \ n /)s.bol?#=> true s.terminate s.bol?#=> truestatic VALUE strscan_bol_p(VALUE self){struct strscanner * p; GET_SCANNER(self,p); 如果(CURPTR(p)> S_PEND(p))返回Qnil; 如果(p-> curr == 0)返回Qtrue; return(*(CURPTR(p) - 1)=='\ n')?Qtrue:Qfalse; } charpos()显示源返回扫描指针的字符位置。在“重置”位置,该值为零。在“终止”位置(即字符串已耗尽)中,此值为字符串的大小。简而言之,它是一个基于0的索引,位于string.s = StringScanner.new(“abcädeföghi”)s中。charpos# - > 0 s.scan_until(/ä/)# - >“abcä”s.pos# - > 5 s.charpos# - > 4static 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)); returnrb_str_length(substr); }检查(模式)显示源这将返回扫描将返回的值,而不会推进扫描指针。匹配寄存器受到影响,但是s = StringScanner.new(“Fri Dec 12 1975 14:39”)s.check / Fri /# - >“Fri”s.pos# - > 0 s.matched# - >“星期五“s.check / 12 /# - > nil s.matched# - > nilMnemonic:它“检查”以查看扫描是否会返回一个值。静态VALUE strscan_check(VALUE self,VALUE re){return strscan_do_scan(self,re,0,1,1); } check_until(pattern)显示源这将返回scan_until将返回的值,而不会推进扫描指针。匹配寄存器受到影响,但是s = StringScanner.new(“Fri Dec 12 1975 14:39”)s.check_until / 12 /# - >“Fri Dec 12”s.pos# - > 0 s.matched# - > 12Mnemonic:它检查scan_until是否会返回一个值。静态值VALUE strscan_check_until(VALUE self,VALUE re){return strscan_do_scan(self,re,0,1,0); } clear()显示源代码等同于终止。这种方法已经过时; use terminate instead.static VALUE strscan_clear(VALUE self){rb_warning(“ StringScanner#clear已过时; 使用#终止代替“);返回strscan_terminate(self);} concat(str)显示源附加str到被扫描的字符串。此方法不影响扫描指针。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); 回归自我; }空?()显示源相当于eos ?. 这种方法已经过时,请使用eos?instead.static VALUE strscan_empty_p(VALUE self){rb_warning(“StringScanner#empty?已过时;使用#eos?改为”); 返回strscan_eos_p(self); } eos?()显示源返回true如果扫描指针位于字符串的结尾处。= StringScanner.new('test string')p s.eos?#=> false s.scan(/ test /)p s.eos?#=> false s.terminate p s.eos?#=> truestatic VALUE strscan_eos_p(VALUE self){struct strscanner * p; GET_SCANNER(self,p); 返回EOS_P(p)?Qtrue:Qfalse; } exists ?(pattern)Show source 看看前方是否pattern存在任何地方在字符串中,不用前进扫描指针。这决定了scan_until是否会返回一个值。s = StringScanner.new('test string')s.exist?/ s /# - > 3 s.scan / test /# - >“test”s.exist?/ s /# - > 2 s.exist?/ e /# - > nilstatic VALUE strscan_exist_p(VALUE self,VALUE re){return strscan_do_scan(self,re,0,0,0); } get_byte()显示源扫描一个字节并返回。这种方法不是多字节字符敏感的。另请参阅:getch.s = StringScanner.new('ab')s.get_byte#=>“a”s.get_byte#=>“b”s.get_byte#=> nil $ KCODE ='EUC's = StringScanner。新(“\ 244 \ 242”)s.get_byte#=>“\ 244”s.get_byte#=>“\ 242”s.get_byte#=> nilstatic VALUE strscan_get_byte(VALUE self){struct strscanner * p; GET_SCANNER(self,p); CLEAR_MATCH_STATUS(P); 如果(EOS_P(p))返回Qnil; p-> prev = p-> curr; P-> CURR ++; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } getbyte()显示源相当于get_byte。这种方法已经过时; 改用get_byte.static VALUE strscan_getbyte(VALUE self){rb_warning(“StringScanner#getbyte已过时;用#get_byte改为”); 返回strscan_get_byte(self); } getch()显示源扫描一个字符并将其返回。这种方法是多字节字符敏感的。s = StringScanner.new(“ab”)s.getch#=>“a”s.getch#=>“ n = $ KCODE ='EUC's = StringScanner.new(“\ 244 \ 242”)s.getch#=>“\ 244 \ 242”#EUC-JP中的日语hira-kana“A”s.getch#=> nilstatic VALUE strscan_getch(VALUE self){struct strscanner * p; 长长的; GET_SCANNER(self,p); CLEAR_MATCH_STATUS(P); 如果(EOS_P(p))返回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; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:n = $ KCODE ='EUC's = StringScanner.new(“\ 244 \ 242”)s.getch#=>“\ 244 \ 242”#EUC-JP中的日语hira-kana“A”s.getch#=> nilstatic VALUE strscan_getch(VALUE self){struct strscanner * p; 长长的; 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; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:)s.getch#=>“\ 244 \ 242”#EUC-JP中的日语hira-kana“A”s.getch#=> nilstatic VALUE strscan_getch(VALUE self){struct strscanner * p; 长长的; GET_SCANNER(self,p); CLEAR_MATCH_STATUS(P); 如果(EOS_P(p))返回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; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:)s.getch#=>“\ 244 \ 242”#EUC-JP中的日语hira-kana“A”s.getch#=> nilstatic VALUE strscan_getch(VALUE self){struct strscanner * p; 长长的; GET_SCANNER(self,p); CLEAR_MATCH_STATUS(P); 如果(EOS_P(p))返回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; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:nilstatic VALUE strscan_getch(VALUE self){struct strscanner * p; 长长的; GET_SCANNER(self,p); CLEAR_MATCH_STATUS(P); 如果(EOS_P(p))返回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; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:nilstatic VALUE strscan_getch(VALUE self){struct strscanner * p; 长长的; GET_SCANNER(self,p); CLEAR_MATCH_STATUS(P); 如果(EOS_P(p))返回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; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:S_RESTLEN(P)); p-> prev = p-> curr; p-> curr + = len; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:S_RESTLEN(P)); p-> prev = p-> curr; p-> curr + = len; 匹配的(P); adjust_registers_to_matched(P); 返回extract_range(p,p-> prev + p-> regs.beg [0],p-> prev + p-> regs.end [0]); } inspect()显示源返回一个表示StringScanner对象的字符串,显示:
  • 当前位置
  • 字符串的大小
  • 扫描指针周围的字符

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) 显示源

测试给定pattern是否与当前扫描指针匹配。返回匹配的长度,或nil。扫描指针不前进。

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() 显示源

返回最后匹配的字符串。

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?() 显示源

true如果最后一场比赛成功,则返回。

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() 显示源

返回最近匹配的大小(请参阅匹配),或者nil最近没有匹配。

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) 显示源

提取一个对应的字符串string[pos,len],而不用提前扫描指针。

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) 显示源

相当于偷看。这种方法已经过时; 改用peek。

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

pointer() 显示源

返回扫描指针的字节位置。在“重置”位置,该值为零。在“终止”位置(即字符串已耗尽)中,此值是字符串的字节大小。

简而言之,这是一个基于0的字符串字节索引。

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) 显示源

设置扫描指针的字节位置。

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() 显示源

返回扫描指针的字节位置。在“重置”位置,该值为零。在“终止”位置(即字符串已耗尽)中,此值是字符串的字节大小。

简而言之,这是一个基于0的字符串字节索引。

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) 显示源

设置扫描指针的字节位置。

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() 显示源

返回的最后一次扫描的-match(在正则表达式的意义)。

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() 显示源

返回最后一次扫描的匹配(正则表达式意义上的)。

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() 显示源

重置扫描指针(索引0)并清除匹配的数据。

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

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

rest() 显示源

返回字符串的“休息”(即扫描指针之后的所有内容)。如果没有更多的数据(eos?= true),它会返回""

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?() 显示源

如果字符串中有更多数据,则返回true。见eos ?. 这种方法已经过时; 使用eos?代替。

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() 显示源

s.rest_size相当于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() 显示源

s.restsize相当于s.rest_size。这种方法已经过时; 改用rest_size。

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

scan(pattern) → String 显示源

尝试与pattern当前位置匹配。如果匹配,扫描仪会推进“扫描指针”并返回匹配的字符串。否则,扫描仪会返回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)显示源文件

测试给定pattern是否与当前扫描指针匹配。如果advance_pointer_p是,则提前扫描指针。如果return_string_p为true,则返回匹配的字符串。匹配寄存器受到影响。

“full”意思是“#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) 显示源

扫描字符串,直到pattern匹配。返回包含匹配结束的子串,并将扫描指针前进到该位置。如果没有匹配,nil则返回。

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)显示源文件

扫描字符串,直到pattern匹配。提前扫描指针advance_pointer_p,否则不提示。如果return_string_p为true,则返回匹配的字符串,否则返回高级字节数。该方法确实会影响匹配寄存器。

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

跳过(模式)显示源

试图pattern用扫描指针跳过给定的开始。如果匹配,则扫描指针前进到匹配结束,并返回匹配的长度。否则,nil返回。

它与扫描类似,但不返回匹配的字符串。

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) 显示源

提高扫描指针直到pattern匹配并消耗。返回高级字节数,或者nil如果找不到匹配项。

pattern预计匹配,并将扫描指针前进到匹配结束。返回高级字符数,或者nil如果匹配失败。

它与scan_until类似,但不返回干预字符串。

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() 显示源

返回正在扫描的字符串。

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

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

string=(str) 显示源

更改正在扫描的字符串str并重置扫描仪。退货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;
}

终止显示源

明确

将扫描指针设置为字符串的结尾并清除匹配的数据。

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() 显示源

将扫描指针设置为上一个位置。只记住一个先前的位置,并且每次扫描操作都会改变。

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;
}

私有实例方法

dup显示源文件

克隆

复制一个StringScanner对象。

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;
}
StringScanner
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct