BLOGTIMES
2013/09/03

Ruby 1.8 の文字列を slice したときにできる壊れたマルチバイト文字を取り除く

  ruby  programming 
このエントリーをはてなブックマークに追加

最近は Ruby 1.8.x を使うことも少なくなってきましたが、日本語を含んだ String を slice() を使って切り出そうとしてハマってしまったのでメモ。
すっかり忘れていましたが、 Ruby 1.8 の String の slice() はマルチバイトとか関係なくバイト単位で無理矢理ぶった切ってしまうという仕様なのでした。

具体的にはこんな感じの処理です。

str = "あいうえお" p str[1,10]

これを実行すると「あ」のマルチバイトの一部と、「え」のマルチバイトの一部が含まれた下記のような String が得られます。

"\201\202いう・

今回は特に綺麗にマルチバイトの文字を取り出したいというよりは、ゴミが出なければ OK という感じだったので、このゴミを取り除いてみます。

先人の知恵を頼る

昔からこの手の問題はあったと思うので、みんなどのようにこの問題に対処しているのかと思ってしらべてみたら正規表現を使って slice(/\A.{0,}/m) とするパターン*1が沢山出てきました。

先ほどの例を書き換えてみるとこんな感じでしょうか。

str = "あいうえお" p str[1,10].slice(/\A.{0,}/m)

確かに末尾のゴミは消えたのですが、残念ながら行頭のゴミはそのままでした。

"\201\202いう"

NKF はどうだろうか

仕方が無いので全く別のアプローチを試みることにします。
壊れた文字列を取り除くという意味では一旦コード変換をかけて、戻したりすればいいのかなという単純な発想から NKF を使ってフィルタしてみることにしました。nkf はコード変換しなくてもいいみたいなので、UTF-8 -> UTF-8 に変換する -wW オプションを使っています

require 'nkf' str = "あいうえお" NKF.nkf('-wW',str[1,10])

これで壊れたマルチバイト文字を取り除くことができました。

"いう"

場合によっては文字が余計に取り除かれてしまうことがありますが、今回は気にしないことにします。


トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/6119
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form

コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。

OpenID を使ってログインすることができます。

Identity URL: Yahoo! JAPAN IDでログイン