Spec-Zone.ru › Ruby 3.3

class StringScanner

Родительский класс:
Object

StringScanner обеспечивает операции лексического анализа строки String. Пример использования:

require 'strscan'

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

Анализ строки подразумевает запоминание позиции указателя сканирования, который представляет собой индекс. Цель сканирования — постепенное продвижение вперед, поэтому соответствия ищутся после указателя сканирования; обычно сразу после него.

Для строки “test string”, вот соответствующие позиции указателя сканирования:

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

Когда вы scan для шаблона (регулярное выражение), соответствие должно произойти с символа после указателя сканирования. Если вы используете scan_until, то соответствие может произойти в любом месте после указателя сканирования. В обоих случаях указатель сканирования перемещается сразу за последний символ соответствия, готовый к повторному сканированию со следующего символа. Это демонстрируется приведенным выше примером.

Method Категории

Помимо простых сканеров, существуют и другие методы. Вы можете заглядывать вперед в строку, не выполняя фактическое сканирование. Вы можете получить доступ к последнему совпадению. Вы можете изменять сканируемую строку, сбрасывать или завершать работу сканера, узнавать или изменять положение указателя сканирования, пропускать вперед и так далее.

Перемещение указателя сканирования

  • getch

  • get_byte

  • scan

  • scan_until

  • skip

  • skip_until

Предварительный просмотр

  • check

  • check_until

  • exist?

  • match?

  • peek

Определение текущей позиции

  • beginning_of_line? (#bol?)

  • eos?

  • rest?

  • rest_size

  • pos

Установка текущей позиции

  • reset

  • terminate

  • pos=

Соответствие

  • matched

  • matched?

  • matched_size

  • #[]

  • pre_match

  • post_match

Разное

  • <<

  • concat

  • string

  • string=

  • unscan

Для некоторых методов существуют псевдонимы.

Публичные методы класса

must_C_version Показать исходный код
static VALUE
strscan_s_mustc(VALUE self)
{
    return self;
}

Этот метод определен для обратной совместимости.

new(string, fixed_anchor: false) Показать исходный код
new(string, dup = false)
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;
}

Создает новый объект StringScanner для сканирования заданной string.

Если fixed_anchor равно true, \A всегда соответствует началу строки. В противном случае, \A всегда соответствует текущей позиции.

Аргумент dup устарел и сейчас не используется.

Открытые методы экземпляра

<<(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"
Псевдоним для: concat
[](n) Показать исходный код
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]));
}

Возвращает 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"
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                        # -> ""
beginning_of_line?() Показать исходный код
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;
}

Возвращает true тогда и только тогда, когда указатель сканирования находится в начале строки.

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
captures Показать исходный код
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 = 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;
}

Возвращает подгруппы в последнем совпадении (не включая полное совпадение). Если ранее ничего не было сопоставлено, возвращает nil.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.scan(/(\w+) (\w+) (\d+) /)       # -> "Fri Dec 12 "
s.captures                         # -> ["Fri", "Dec", "12"]
s.scan(/(\w+) (\w+) (\d+) /)       # -> nil
s.captures                         # -> nil
charpos() Показать исходный код
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)));
}

Возвращает позицию символа указателя сканирования. В позиции «reset» это значение равно нулю. В позиции «terminated» (т. е. строка исчерпана), это значение равно размеру строки.

Короче говоря, это индекс, начинающийся с 0, в строку.

s = StringScanner.new("abc\u00e4def\u00f6ghi")
s.charpos                # -> 0
s.scan_until(/\u00e4/)   # -> "abc\u00E4"
s.pos                    # -> 5
s.charpos                # -> 4
check(pattern) Показать исходный код
static VALUE
strscan_check(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 1, 1);
}

Возвращает значение, которое вернул бы scan, не продвигаясь по указателю сканирования. Однако регистр совпадений изменяется.

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

Мнемонически: он «проверяет», вернет ли scan значение.

check_until(pattern) Показать исходный код
static VALUE
strscan_check_until(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 1, 0);
}

Возвращает значение, которое вернул бы scan_until, не продвигаясь по указателю сканирования. Однако регистр совпадений изменяется.

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

Мнемонически: он «проверяет», вернет ли scan_until значение.

clear() Показать исходный код
static VALUE
strscan_clear(VALUE self)
{
    rb_warning("StringScanner#clear is obsolete; use #terminate instead");
    return strscan_terminate(self);
}

Эквивалент terminate. Этот метод устарел; используйте terminate вместо него.

concat(str) Показать исходный код
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;
}

Добавляет 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"
Также является псевдонимом для: <<
empty?() Показать исходный код
static VALUE
strscan_empty_p(VALUE self)
{
    rb_warning("StringScanner#empty? is obsolete; use #eos? instead");
    return strscan_eos_p(self);
}

Эквивалент eos?. Этот метод устарел, используйте eos? вместо него.

eos?() Показать исходный код
static VALUE
strscan_eos_p(VALUE self)
{
    struct strscanner *p;

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

Возвращает true, если указатель сканирования находится в конце строки.

s = StringScanner.new('test string')
p s.eos?          # => false
s.scan(/test/)
p s.eos?          # => false
s.terminate
p s.eos?          # => true
exist?(pattern) Показать исходный код
static VALUE
strscan_exist_p(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 0, 0);
}

Заглядывает вперед, чтобы увидеть, существует ли pattern где-нибудь в строке, не продвигаясь по указателю сканирования. Это определяет, вернет ли scan_until значение.

s = StringScanner.new('test string')
s.exist? /s/            # -> 3
s.scan /test/           # -> "test"
s.exist? /s/            # -> 2
s.exist? /e/            # -> nil
fixed_anchor? → true or false Показать исходный код
static VALUE
strscan_fixed_anchor_p(VALUE self)
{
    struct strscanner *p;
    p = check_strscan(self);
    return p->fixed_anchor_p ? Qtrue : Qfalse;
}

Использует ли scanner режим фиксированной привязки или нет.

Если используется режим фиксированной привязки, \A всегда соответствует началу строки. В противном случае, \A всегда соответствует текущей позиции.

get_byte() Показать исходный код
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]));
}

Сканирует один байт и возвращает его. Этот метод не чувствителен к многобайтовым символам. См. также: getch.

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

s = StringScanner.new("\244\242".force_encoding("euc-jp"))
s.get_byte         # => "\xA4"
s.get_byte         # => "\xA2"
s.get_byte         # => nil
getbyte() Показать исходный код
static VALUE
strscan_getbyte(VALUE self)
{
    rb_warning("StringScanner#getbyte is obsolete; use #get_byte instead");
    return strscan_get_byte(self);
}

Эквивалент get_byte. Этот метод устарел; используйте get_byte вместо него.

getch() Показать исходный код
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]));
}

Сканирует один символ и возвращает его. Этот метод чувствителен к многобайтовым символам.

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

s = StringScanner.new("\244\242".force_encoding("euc-jp"))
s.getch           # => "\x{A4A2}"   # Japanese hira-kana "A" in EUC-JP
s.getch           # => nil
inspect() Показать исходный код
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;
}

Возвращает строку, представляющую объект StringScanner, показывая:

  • текущую позицию

  • размер строки

  • символы вокруг указателя сканирования

    s = StringScanner.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…”>’

match?(pattern) Показать исходный код
static VALUE
strscan_match_p(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 0, 0, 1);
}

Проверяет, соответствует ли заданный pattern текущему указателю сканирования. Возвращает длину совпадения или nil. Указатель сканирования не продвигается.

s = StringScanner.new('test string')
p s.match?(/\w+/)   # -> 4
p s.match?(/\w+/)   # -> 4
p s.match?("test")  # -> 4
p s.match?(/\s+/)   # -> nil
matched() Показать исходный код
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]));
}

Возвращает последнюю найденную строку.

s = StringScanner.new('test string')
s.match?(/\w+/)     # -> 4
s.matched           # -> "test"
matched?() Показать исходный код
static VALUE
strscan_matched_p(VALUE self)
{
    struct strscanner *p;

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

Возвращает true тогда и только тогда, когда последнее совпадение было успешным.

s = StringScanner.new('test string')
s.match?(/\w+/)     # => 4
s.matched?          # => true
s.match?(/\d+/)     # => nil
s.matched?          # => false
matched_size() Show source
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]);
}

Возвращает размер последнего совпадения в байтах или nil если совпадений не было. Это отличается от matched.size, который вернет размер в символах.

s = StringScanner.new('test string')
s.check /\w+/           # -> "test"
s.matched_size          # -> 4
s.check /\d+/           # -> nil
s.matched_size          # -> nil
named_captures → hash Show source
static VALUE
strscan_named_captures(VALUE self)
{
    struct strscanner *p;
    GET_SCANNER(self, p);
    named_captures_data data;
    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;
}

Возвращает хеш строковых переменных, соответствующих регулярному выражению.

scan = StringScanner.new('foobarbaz')
scan.match?(/(?<f>foo)(?<r>bar)(?<z>baz)/)
scan.named_captures # -> {"f"=>"foo", "r"=>"bar", "z"=>"baz"}
peek(len) Show source
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);
}

Извлекает строку, соответствующую string[pos,len], не изменяя указатель сканирования.

s = StringScanner.new('test string')
s.peek(7)          # => "test st"
s.peek(7)          # => "test st"
peep(p1) Show source
static VALUE
strscan_peep(VALUE self, VALUE vlen)
{
    rb_warning("StringScanner#peep is obsolete; use #peek instead");
    return strscan_peek(self, vlen);
}

Эквивалентно peek. Этот метод устарел; используйте peek вместо него.

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
Псевдоним для: pos
pointer=
Псевдоним для: pos=
pos() Show source
static VALUE
strscan_get_pos(VALUE self)
{
    struct strscanner *p;

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

Возвращает позицию указателя сканирования в байтах. В позиции «сброс» это значение равно нулю. В позиции «завершено» (т.е. строка исчерпана), это значение равно размеру строки в байтах.

Короче говоря, это индекс, начинающийся с 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
Также является псевдонимом для: pointer
pos=(n) Show source
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);
}

Устанавливает позицию указателя сканирования в байтах.

s = StringScanner.new('test string')
s.pos = 7            # -> 7
s.rest               # -> "ring"
Также является псевдонимом для: pointer=
post_match() Show source
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));
}

Возвращает post-совпадение (в смысле регулярных выражений) последнего сканирования.

s = StringScanner.new('test string')
s.scan(/\w+/)           # -> "test"
s.scan(/\s+/)           # -> " "
s.pre_match             # -> "test"
s.post_match            # -> "string"
pre_match() Show source
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]));
}

Возвращает pre-совпадение (в смысле регулярных выражений) последнего сканирования.

s = StringScanner.new('test string')
s.scan(/\w+/)           # -> "test"
s.scan(/\s+/)           # -> " "
s.pre_match             # -> "test"
s.post_match            # -> "string"
reset() Show source
static VALUE
strscan_reset(VALUE self)
{
    struct strscanner *p;

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

Сбрасывает указатель сканирования (индекс 0) и очищает данные сопоставления.

rest() Show source
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));
}

Возвращает «остаток» строки (т.е. все после указателя сканирования). Если больше нет данных (eos? = true), возвращает "".

rest?() Show source
static VALUE
strscan_rest_p(VALUE self)
{
    struct strscanner *p;

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

Возвращает true тогда и только тогда, когда в строке есть больше данных. См. eos?. Этот метод устарел; используйте eos? вместо него.

s = StringScanner.new('test string')
# These two are opposites
s.eos? # => false
s.rest? # => true
rest_size() Show source
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);
}

s.rest_size эквивалентно s.rest.size.

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

s.restsize эквивалентно s.rest_size. Этот метод устарел; используйте rest_size вместо него.

scan(pattern) → String Show source
static VALUE
strscan_scan(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 1, 1);
}

Пытается выполнить сопоставление с pattern в текущей позиции. Если есть совпадение, сканер перемещает «указатель сканирования» и возвращает совпавшую строку. В противном случае сканер возвращает nil.

s = StringScanner.new('test string')
p s.scan(/\w+/)   # -> "test"
p s.scan(/\w+/)   # -> nil
p s.scan(/\s+/)   # -> " "
p s.scan("str")   # -> "str"
p s.scan(/\w+/)   # -> "ing"
p s.scan(/./)     # -> nil
scan_full(pattern, advance_pointer_p, return_string_p) Show source
static VALUE
strscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)
{
    return strscan_do_scan(self, re, RTEST(s), RTEST(f), 1);
}

Проверяет, соответствует ли заданный pattern текущему указателю сканирования. Перемещает указатель сканирования, если advance_pointer_p истинно. Возвращает совпавшую строку, если return_string_p истинно. Регистр совпадений изменяется.

«full» означает «#scan с полными параметрами».

scan_until(pattern) Show source
static VALUE
strscan_scan_until(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 1, 0);
}

Сканирует строку до тех пор, пока не будет найдено совпадение с 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
search_full(pattern, advance_pointer_p, return_string_p) Show source
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. Перемещает указатель сканирования, если advance_pointer_p, в противном случае нет. Возвращает совпавшую строку, если return_string_p истинно, в противном случае возвращает количество продвинутых байт. Этот метод изменяет регистр совпадений.

size Show source
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);
}

Возвращает количество подгрупп в последнем совпадении. Полное совпадение считается подгруппой.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.scan(/(\w+) (\w+) (\d+) /)       # -> "Fri Dec 12 "
s.size                             # -> 4
skip(pattern) Show source
static VALUE
strscan_skip(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 0, 1);
}

Пытается пропустить заданный pattern начиная с указателя сканирования. Если он совпадает, указатель сканирования перемещается в конец совпадения, и возвращается длина совпадения. В противном случае, возвращается nil.

Это похоже на scan, но без возврата совпадающей строки.

s = StringScanner.new('test string')
p s.skip(/\w+/)   # -> 4
p s.skip(/\w+/)   # -> nil
p s.skip(/\s+/)   # -> 1
p s.skip("st")    # -> 2
p s.skip(/\w+/)   # -> 4
p s.skip(/./)     # -> nil
skip_until(pattern) Show source
static VALUE
strscan_skip_until(VALUE self, VALUE re)
{
    return strscan_do_scan(self, re, 1, 0, 0);
}

Перемещает указатель сканирования до тех пор, пока pattern не будет найден и обработан. Возвращает количество пропущенных байтов или nil, если совпадение не найдено.

Заглядывает вперёд, чтобы найти совпадение pattern, и перемещает указатель сканирования в конец совпадения. Возвращает количество пропущенных символов или nil, если совпадение не удалось.

Это похоже на scan_until, но без возврата промежуточной строки.

s = StringScanner.new("Fri Dec 12 1975 14:39")
s.skip_until /12/           # -> 10
s                           #
string() Show source
static VALUE
strscan_get_string(VALUE self)
{
    struct strscanner *p;

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

Возвращает сканируемую строку.

string=(str) Show source
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;
}

Изменяет сканируемую строку на str и сбрасывает сканер. Возвращает str.

terminate Show source
clear
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() Show source
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;
}

Устанавливает указатель сканирования в предыдущее положение. Запоминается только одно предыдущее положение, и оно меняется при каждой операции сканирования.

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
values_at( i1, i2, ... iN ) → an_array Show source
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;
}

Возвращает подгруппы в последнем совпадении с заданными индексами. Если ранее совпадений не было, возвращает nil.

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

Приватные методы экземпляра

dup Show source
clone
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 Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API