2011年4月30日

[ruby-list:48022] Re: 文字列を正規表現にマッチする部分と他の部分に分割

5.5 さん

信岡です。

>> result = ''
>> str = 'ab12cd'
>> while true do
>> i = ( str =~ /\d+/ )

>> result<< $`.upcase<< "<#{$&}>"
>> str = $'
>> end
>> result<< str #=> "AB<12>CD"
>
> これだとループの二回めで =~ が失敗し,$`.upcase で例外が発生しますが,

ああっ、ごめんなさい。 メールを書きながら適当にいじっていて
直すのを忘れてたみたいです。

> 大きなテキストで,かつマッチ箇所が多数あると,大量の文字列ゴミが出ま
> すよね。

そうですね、ごみは出てしまいますね。 ごみを出さないようにするには、
$' を str に代入するのではなく、マッチした位置を index として記録しておいて、
String#match メソッドの第 2 引数に渡すような処理にするとか、すれば
いいのでしょうか。

>> 正規表現中にグルーピングのための括弧があると、とのことですが、
>> グルーピングにはグルーピングのための記法 ("(?:XXX)" の形式) が
>> あるので、これを用いれば問題にはならないと思います。
>
> そうなのですが,以下の理由で避けました。
>
> [1] /(\d).\1/ のように正規表現中で後方参照を使いたい場合もある。
> [2] あまり慣れていない人に使ってもらうツールを考えていたので,
>  エンドユーザーに (?: ) の使用を強いるのが憚られた。
> [3] ブロック内でマッチデータを積極的に使いたい場合もある。

なるほど。
後方参照のための括弧は 「キャプチャリングのための括弧」 であって、
「グルーピングのための括弧」 ではないので、単にグルーピングするだけなら
"(?:XXX)" を使えばいいかなーと思ったのですが、キャプチャリングも必要なら
確かにダメですね。。


実を言うと私も 5.5 さんが提案されたようなメソッドが欲しいなーと思ったことがあって、
その時は自分で適当にそういうメソッドを作ったのですが、確かに実行速度などを
考えると C での実装で提供して貰えるとありがたいですよね。

ただ、String クラスや Regexp クラスに新しく追加すべきメソッドかというとそうでもないなぁ、
とも感じていて。。 追加されるとすれば StringScanner あたりが適当ですかね。

> 一般論として、実際のユースケースを示した方が良いです。
> 特に新しいメソッドを提案するときには。

ちなみに私がそういうメソッドを欲しいと思ったのは、XML のタグ部分 ('<' と '>' で囲まれた部分)
とそれ以外の部分を分けるという処理を書いたときです。 以下のように書けると便利ですよね。

xml_str.each_segment /<[^>]*>/ do |str, matched|
if matched
proc_for_tag( str )
else
proc_for_text( str )
end
end


--
信岡 ゆう (NOBUOKA Yu)


投稿者 xml-rpc : 2011年4月30日 19:25
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/103417
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。