APIdock / Ruby
/
method

sub!

ruby latest stable - Class: String
sub!(*args)
public

Performs the same substitution as String#sub in-place.

Returns str if a substitution was performed or nil if no substitution was performed.

static VALUE
rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
{
 VALUE pat, repl, hash = Qnil;
 int iter = 0;
 int tainted = 0;
 long plen;
 int min_arity = rb_block_given_p() ? 1 : 2;
 long beg;
 rb_check_arity(argc, min_arity, 2);
 if (argc == 1) {
 iter = 1;
 }
 else {
 repl = argv[1];
 hash = rb_check_hash_type(argv[1]);
 if (NIL_P(hash)) {
 StringValue(repl);
 }
 tainted = OBJ_TAINTED_RAW(repl);
 }
 pat = get_pat_quoted(argv[0], 1);
 str_modifiable(str);
 beg = rb_pat_search(pat, str, 0, 1);
 if (beg >= 0) {
 rb_encoding *enc;
 int cr = ENC_CODERANGE(str);
 long beg0, end0;
 VALUE match, match0 = Qnil;
 struct re_registers *regs;
 char *p, *rp;
 long len, rlen;
 match = rb_backref_get();
 regs = RMATCH_REGS(match);
 if (RB_TYPE_P(pat, T_STRING)) {
 beg0 = beg;
 end0 = beg0 + RSTRING_LEN(pat);
 match0 = pat;
 }
 else {
 beg0 = BEG(0);
 end0 = END(0);
 if (iter) match0 = rb_reg_nth_match(0, match);
 }
 if (iter || !NIL_P(hash)) {
 p = RSTRING_PTR(str); len = RSTRING_LEN(str);
 if (iter) {
 repl = rb_obj_as_string(rb_yield(match0));
 }
 else {
 repl = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
 repl = rb_obj_as_string(repl);
 }
 str_mod_check(str, p, len);
 rb_check_frozen(str);
 }
 else {
 repl = rb_reg_regsub(repl, str, regs, RB_TYPE_P(pat, T_STRING) ? Qnil : pat);
 }
 enc = rb_enc_compatible(str, repl);
 if (!enc) {
 rb_encoding *str_enc = STR_ENC_GET(str);
 p = RSTRING_PTR(str); len = RSTRING_LEN(str);
 if (coderange_scan(p, beg0, str_enc) != ENC_CODERANGE_7BIT ||
 coderange_scan(p+end0, len-end0, str_enc) != ENC_CODERANGE_7BIT) {
 rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s",
 rb_enc_name(str_enc),
 rb_enc_name(STR_ENC_GET(repl)));
 }
 enc = STR_ENC_GET(repl);
 }
 rb_str_modify(str);
 rb_enc_associate(str, enc);
 tainted |= OBJ_TAINTED_RAW(repl);
 if (ENC_CODERANGE_UNKNOWN < cr && cr < ENC_CODERANGE_BROKEN) {
 int cr2 = ENC_CODERANGE(repl);
 if (cr2 == ENC_CODERANGE_BROKEN ||
 (cr == ENC_CODERANGE_VALID && cr2 == ENC_CODERANGE_7BIT))
 cr = ENC_CODERANGE_UNKNOWN;
 else
 cr = cr2;
 }
 plen = end0 - beg0;
 rp = RSTRING_PTR(repl); rlen = RSTRING_LEN(repl);
 len = RSTRING_LEN(str);
 if (rlen > plen) {
 RESIZE_CAPA(str, len + rlen - plen);
 }
 p = RSTRING_PTR(str);
 if (rlen != plen) {
 memmove(p + beg0 + rlen, p + beg0 + plen, len - beg0 - plen);
 }
 memcpy(p + beg0, rp, rlen);
 len += rlen - plen;
 STR_SET_LEN(str, len);
 TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str));
 ENC_CODERANGE_SET(str, cr);
 FL_SET_RAW(str, tainted);
 return str;
 }
 return Qnil;
}

AltStyle によって変換されたページ (->オリジナル) /