From: matz@... (Yukihiro Matsumoto) Date: 1999-06-28T15:32:28+09:00 Subject: [ruby-dev:7246] Re: String#rindex with arbitrary starting point まつもと ゆきひろです In message "[ruby-dev:7233] Re: String#rindex with arbitrary starting point" on 99/06/27, WATANABE Hirofumi writes: |pos が位置なのか長さなのかというあたりがはっきりしてないのが |バグの原因のようですね. pos は位置にしてみました. |ついでに "" や // にも対応したつもり. どーもです。やはり場当たり的な対応に限界が出ましたね。 ただ、そのまま反映するのではなく、ちょっと修正しました。 というのも、今の仕様はその範囲内に部分文字列が存在しないとい けないという仕様なんですが、Perlに合わせて、その場所から検索 してマッチしてればOKに変更します。だから、 "abcdef".rindex("abc", 0) は0を返すようになります。 |ただし Regexp のときは不完全. これはregex.cで、BMサーチでは範囲内に部分文字列が存在するこ とを仮定してたからです。これも修正しました。 |ところで index, rindex はマルチバイト対応しなくていいんだっけ? 正規表現を含まないマッチでは対応しないつもりです。対応するな らjcode.rbを使ってでしょう。正規表現は対応するつもりですが、 逆方向マッチはちゃんと出来てる自信がないです。 まつもと ゆきひろ /:|) --- string.c 1999/06/25 09:02:48 1.1.1.3.2.20 +++ string.c 1999/06/28 06:31:47 @@ -632,20 +632,30 @@ switch (TYPE(sub)) { case T_REGEXP: - pos = rb_reg_search(sub, str, pos, 1); - if (pos >= 0) return INT2NUM(pos); + if (RREGEXP(sub)->len) { + pos = rb_reg_search(sub, str, pos, 1); + } + if (pos >= 0) return INT2NUM(pos); break; case T_STRING: + len = RSTRING(sub)->len; /* substring longer than string */ - if (pos < RSTRING(sub)->len) return Qnil; + if (RSTRING(str)->len < len) return Qnil; + if (RSTRING(str)->len - pos < len) { + pos = RSTRING(str)->len - len; + } sbeg = RSTRING(str)->ptr; - s = RSTRING(str)->ptr + pos - RSTRING(sub)->len; + s = RSTRING(str)->ptr + pos; t = RSTRING(sub)->ptr; - len = RSTRING(sub)->len; - while (sbeg <= s) { - if (*s == *t && memcmp(s, t, len) == 0) { - return INT2NUM(s - RSTRING(str)->ptr); + if (len) { + while (sbeg <= s) { + if (*s == *t && memcmp(s, t, len) == 0) { + return INT2NUM(s - RSTRING(str)->ptr); + } + s--; } - s--; + } + else { + return INT2NUM(pos); } break; @@ -654,5 +664,5 @@ { int c = FIX2INT(sub); - char *p = RSTRING(str)->ptr + pos - 1; + char *p = RSTRING(str)->ptr + pos; char *pbeg = RSTRING(str)->ptr; --- regex.c 1999/06/25 09:02:46 1.1.1.3.2.26 +++ regex.c 1999/06/28 06:31:47 @@ -2963,5 +2963,5 @@ pos = pend; pend = pbeg; pbeg = pos; } - if (pend > size) pend = size; + pend = size; if (bufp->options & RE_OPTIMIZE_NO_BM) { pos = slow_search(bufp->must+1, len,