SSブログ

bogofilter-nihongo.rb の ruby 2.0 対応 (2) [自作ソフト]

長くなったので、分割。初めは此方、
 [bogofilter-nihongo.rb の ruby 2.0 対応 (1):matsuan の器用貧乏日記:So-netブログ]
  http://kiyoubinbou-matsuan.blog.so-net.ne.jp/2013-06-08

3. ruby 2.0 に於ける日本語


3.1. 日本語判別


大分、変わってそうで、少し勉強。String#encode を使うことは判ったのだけど、そもそも、文字列が保持している encode 情報が怪しい。
ググったら、こんなことが書いてある。
 [Ruby 1.9で文字コードの自動判別を行う - @masuidrive blog]
  http://blog.masuidrive.jp/index.php/2012/01/06/encoding-auto-detection-on-ruby-1-9/

お薦めに従って、charlock_holmes をインストール
#sudo apt-get install libicu-dev
#gem install charlock_holmes


3.2. charlock_holmes を試してみる


簡単なコードを書いてみた。
#!/home/hoge/.rbenv/versions/2.0.0-dev/bin/ruby
# coding: euc-jp

require 'MeCab'
require 'rmail'
require 'charlock_holmes'

def main
  $stderr.puts "default encoding        : #{__ENCODING__}"

  Encoding.default_internal = 'euc-jp'
  STDOUT.set_encoding('euc-jp') 

  mail = RMail::Parser.read($stdin)

  m = mail.body

  $stderr.puts "body encoding           : #{m.encoding}"
  enc = CharlockHolmes::EncodingDetector.detect(m)[:encoding]  
  $stderr.puts "estimated body encoding : #{enc}"

  m.force_encoding(enc)
  $stderr.puts "after force encode      : #{m.encoding}"
  
  m = m.encode('euc-jp')
  
  $stderr.puts "after euc encode        : #{m.encoding}"
  
  rawbody = MeCab::Tagger.new("-O wakati")
  $stderr.puts "after Mecab::wakati     : #{rawbody.encoding}"

  rawbody.force_encoding('euc-jp')
  $stderr.puts "after force encode      : #{rawbody.encoding}"

  $stdout.write rawbody

end

main

これに、単純なメール(iso-2022-jp でシングルパート)を通してみた。結果は、
default encoding        : EUC-JP
body encoding           : UTF-8
estimated body encoding : ISO-2022-JP
after force encode      : ISO-2022-JP
after euc encode        : EUC-JP
after Mecab::wakati     : ASCII-8BIT
after force encode      : EUC-JP

なんだかな〜

いろんな、文字コードのメールを通してみた結果は、
・自動判別は、当てにならない
・charlock_holmes は、大丈夫そう
・EUC 文字列を 分かち書きすると、ascii-8bit と判断されてしまう。せめて、情報は保持して欲しいよな〜

3.3. encode で失敗してないのに、puts でエラー


いろんなメールを通していたら、変なことが偶に起きる。
encode で失敗してないのに、puts でエラーに成るのだ。どうやら、puts で出力できない文字が有るようだ。最初、dump が使えるかと思ったのだけれど、これは、まともな文字コードまでエスケープを可視化してしまうので駄目だった。
で、たどり着いたのがこれ。

  m = m.encode('euc-jp')

をこれで置き換える。
  ec = Encoding::Converter.new(enc, "euc-jp", :invalid => :replace, :undef => :replace)
  ec.replacement = 
""
m = ec.convert(m)


長くなったので、続きはこちらへ
 [bogofilter-nihongo.rb の ruby 2.0 対応 (3):matsuan の器用貧乏日記:So-netブログ]
  http://kiyoubinbou-matsuan.blog.so-net.ne.jp/2013-06-08-2


nice!(0)  コメント(0)  トラックバック(1) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 1

bogofilter-nihongo.r..bogofilter-nihongo.r.. ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。