Lightweight Language Lovers

PythonとRubyを比較してみる(Rubyだと日本語の扱いが楽です)

Ruby だと日本語の扱いが楽で、基本的な漢字の切り出しや機種依存の判定などは Ruby FAQ 日本語の取り扱い
やり方が書かれてあり、実はコーディングしなくても良かったのです。
(実際、SjisChars_py.rb では $KCODE = 'NONE' としてわざわざこの機能を殺しています。)

しかし、特徴をつかむことが目的ですから、ここでは日本語の扱いなどをみてみます。

まず、

class SjisChars
  
  $KCODE = "SJIS"
  KU13 = 0x8740..0x879c
  KU89_92 = 0xED40..0xEEFC
  KU115_9 = 0xFA40..0xFC4B
  GAIJI = 0xF040..0xF9FC

ですが、$KODE で漢字コードを設定しておくことが出来ます。これにより2バイト文字を解釈してくれます。
from..to で、コードの範囲を範囲オブジェクトとして定義しています。定数は大文字で始めます。

  def initialize(chars)
    @chars = chars
    @reKisyu = mkRegexp(KU13, KU89_92, KU115_9)
    @reGaiji = mkRegexp(GAIJI)
  end
  
  def mkRegexp(*ra)
    ra.map! {|r| "[%s-%s]" % [[r.first].pack("n"), [r.last].pack("n")]}
    Regexp.compile(ra.join("|"))
  end

初期化の部分で、インスタンス変数の設定と、コード範囲を表す正規表現オブジェクトの生成を行っています。 Ruby FAQ を見ると、正規表現に漢字を使うことができるがわかります。
コード範囲から、/[始-終]|[始-終]|../ の正規表現を得るのが目的です。

  1. ra.map! ... 配列の各要素(コード範囲)に{ }を適用して更新
  2. {|r| }... それぞれのコード範囲(r)について、先頭(r.first)と最後(r.last)を数値から漢字に変換(ネットワークバイトオーダー("n")でpack)後、[始-終]の形に編集("[%s-%s]" %)
  3. [%s-%s]それぞれを | で join して目的とする正規表現に変換(Regexp.compile)

  def scanSjis
    @chars.split(//).each {|c| yield c, isKanji(c), isGaiji(c), isKisyu(c)}
  end
  
  def isKanji(c)
    c.length == 2
  end
  
  def isGaiji(c)
    @reGaiji.match(c) != nil
  end
  
  def isKisyu(c)
    @reKisyu.match(c) != nil
  end

は、文字列から漢字を考慮して切り出して(split(//))、判定しながら yield しています。
文字列.scan(正規表現)を使うと簡単なのですが、他のプログラムに組み込んで使う場合、 順序を保ったまま判定結果が返ってきたほうが良いので、このようにしています。

hexprint はおまけです。

#プログラムの解説は次回にしたいと思います。 --> ../Ruby2


CategoryPython CategoryRuby