Module: MatchAt

Defined in:
lib/match_at.rb,
ext/match_at/match_at.c

Overview

This library is a Refinements. By use-ing it your namespace has String#match_at.

Constant Summary collapse

VERSION =
3

Class Method Summary collapse

Class Method Details

.match_at(str, rexp, pos) ⇒ MatchData?

Note:

It does not update $~.

Try to construct a MatchData at str's pos position. If that's possible return the allocated MatchData. Otherwise, returns nil.

Parameters:

  • str (String)

    target string.

  • rexp (Regexp)

    pattern to match.

  • pos (Integer)

    str's index, in character.

Returns:

  • (MatchData)

    successful match.

  • (nil)

    failure in match.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'ext/match_at/match_at.c', line 74

VALUE
match_at(VALUE mod, VALUE str, VALUE rexp, VALUE pos)
{
    OnigRegion region   = { 0 };
    VALUE ret           = Qnil;
    OnigPosition result = do_match(str, rexp, pos, &region);

    if (result >= 0) {
        int err;
        ret = rb_funcall(rb_cMatch, rb_intern("allocate"), 0);
        err = rb_reg_region_copy(RMATCH_REGS(ret), &region);
        if (err) {
            rb_memerror();
        }
        else {
            RMATCH(ret)->regexp = rexp;
            RMATCH(ret)->str    = rb_str_new_frozen(str); /* copy */
            OBJ_INFECT(ret, rexp);
            OBJ_INFECT(ret, str);
            /* no backref introduced, OK write barrier. */
        }
    }
    onig_region_free(&region, 0);
    return ret;
}

.match_at?(str, rexp, pos) ⇒ true, false

Match the rexp against str's position pos. This is lightweight because no MatchData is allocated.

Parameters:

  • str (String)

    target string.

  • rexp (Regexp)

    pattern to match.

  • pos (Integer)

    str's index, in character.

Returns:

  • (true)

    successful match.

  • (false)

    failure in match.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'ext/match_at/match_at.c', line 42

VALUE
match_at_p(VALUE mod, VALUE str, VALUE rexp, VALUE pos)
{
    OnigPosition result = do_match(str, rexp, pos, NULL);

    if (result >= 0) {
        long n           = NUM2LONG(pos);
        rb_encoding *enc = rb_enc_get(str);
        const char *beg  = rb_string_value_ptr(&str);
        const char *end  = RSTRING_END(str);
        const char *ptr  = rb_enc_nth(beg, end, n, enc);
        const char *term = &ptr[result];
        long len         = rb_enc_strlen(ptr, term, enc);

        return LONG2NUM(len);
    }
    else {
        return Qnil;
    }
}