けいじゅ@日本ラショナルソフトウェアです.

In [ruby-list :18383 ] the message: "[ruby-list:18383] Re: [book]
csv_split2 ", on Nov/04 15:55(JST) Shin-ichiro Hara writes:

>原です。

>|scan(/(?:^|,)(?:"((?:[^"]|"")*)"|([^,]*))/).collect{|m1,m2| m2 || m1.gsub(/""/, '"')}
>
>根本には、パターンが空にマッチする時の scan の動作は恣意的ならざるを
>えないという問題があるので、潔くケツに , を補って
>
>def csv_split(s)
>  (s + ',').scan(/"((?:[^"]|"")*)",|([^,]*),/).collect{ |m1, m2|
>    m2 || m1.gsub(/""/, '"')
>  }
>end
>
>がいいかもしれない。

おお. これは結構エレガントですね. | の使い方がよい.

じつは. 本の方の例題でもこの考えをベースにしたものを乗せることにしました. 

def csv_split(source, delimiter = ',')
  csv = []
  qd = Regexp.quote(delimiter)		# (A) 正規表現のエスケープ
  # (B) String#scan
  source += delimiter                   # (C) 文字列の末尾にデリミタを追加
  source.scan(/(([^"#{qd}][^#{qd}]*|)|"(([^"]|"")*)")#{qd}/) do
    |match, m1, m2, *rests|
    if m2
      csv.push m2.gsub(/""/, '"')       # 配列の末尾に要素を追加
    else
      csv.push m1
    end
  end
  csv
end

締め切りも迫っていますし, あまり変えると, 本文がガタガタになるので... あ
とは, MLでの議論を見てねってことにしました(^^;;;

>|# このメイルスレッドはなかなかおもしろい内容がありますが, 本には反映し切
>|# れそうもないなあ...
>
>なんかいい方法はないかなあ、、、

ですね. 

__
..............................石塚 圭樹@日本ラショナルソフトウェア...
----------------------------------->> e-mail: keiju / rational.com <<---