Rubyで固定長のCP932(Shift_JIS)ファイルを扱う
哀しいことにCSVなどでなく固定文字列長のCP932ファイルからインポートを行わないといけなくなったのでその対処方法。
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin15]
データのイメージ
123456abcdef池袋 イケブクロ 10 123456abcdef目白 メジロ 10 123456abcdef高田馬場 タカダノババ 10
全角=2バイト, 半角1バイトという前提でデータファイルが設計されているが、Ruby 2.x で文字列として全角半角問わず1文字は1文字としてカウントされる為、文字数がズレることがある。
対処
byteslice
を使い特定バイト位置をスライスする。
irb(main):023:0> File.foreach('test.txt') { |line| p line.byteslice(12...58); p line.byteslice(58...107) } "\x92r\x91\xDC " "\xB2\xB9\xCC\u07B8\xDB " "\x96ڔ\x92 " "Ҽ\xDE\xDB " "\x8D\x82\x93c\x94n\x8F\xEA " "\xC0\xB6\xC0\xDE\xC9\xCA\xDE\xCA\xDE "
utf-8に変換する
irb(main):022:0> File.foreach('test.txt') { |line| p line.byteslice(12...58).encode('utf-8', 'cp932'); p line.byteslice(58...107).encode('utf-8', 'cp932') } "池袋 " "イケブクロ " "目白 " "メジロ " "高田馬場 " "タカダノババ "
必要に応じてstripする
irb(main):021:0> File.foreach('test.txt') { |line| p line.byteslice(12...58).encode('utf-8', 'cp932').strip; p line.byteslice(58...107).encode('utf-8', 'cp932').strip } "池袋" "イケブクロ" "目白" "メジロ" "高田馬場" "タカダノババ"
- 作者:リンダ・リウカス
- 発売日: 2016/05/19
- メディア: ハードカバー