名称

ShiftJIS::Collate - Shift-JIS 文字列の照合


概要

  use ShiftJIS::Collate;
  @sorted = ShiftJIS::Collate->new(%tailoring)->sort(@source);


詳細

このモジュールは、JIS X 4061:1996 (日本語文字列照合順番) に基づいて、Shift-JIS 文字列を照合、整列するための関数を提供します。

このモジュールは JIS X 4061:1996 の実装の一つであり、 照合規則は、上記規格に基づいています。 処理系定義項目も参照のこと。

コンストラクタとテーラリング

new メソッドは、コレータ・オブジェクトを返却します。

   $Collator = ShiftJIS::Collate->new(
      ignoreChar => $regexIgnoredChar,
      kanji => $kanji_class,
      katakana_before_hiragana => $bool,
      level => $collationLevel,
      position_in_bytes => $bool,
      tounicode  => \&sjis_to_unicode,
      preprocess => \&preprocess,
      upper_before_lower => $bool,
   );
   # もし %tailoring が偽(空リスト)なら、
   # $Collator はデフォルトの照合をします。
ignoreChar
与えられた正規表現にマッチする文字を、照合に際して無視します。

例えば、もし長音記号とその半角形を無視したいなら、以下のようにします。

   ignoreChar => '^(?:\x81\x5B|\xB0)',

katakana_before_hiragana
デフォルトでは、平仮名は対応する片仮名よりも前の順序になります。

このパラメータが真なら、この順序を逆にして、片仮名を平仮名の前に置きます。

kanji
使用する漢字文字クラスを指定します。漢字文字クラスについて、詳細は後述。
  Class 1: 最小漢字文字クラス
  Class 2: 基本漢字文字クラス
  Class 3: 拡張漢字文字クラス

漢字文字クラスは 1, 2, 3 のいずれかの整数値で指定します。 省略された場合、2 が用いられます。

この文字クラスでは、拡張漢字文字クラスはサポートされません。 なぜなら、Shift-JIS のレパートリには、すべての CJK 統合漢字が 定義されないからです。

しかし、漢字文字クラスとして 3 を指定した場合には、 第1および第2水準の漢字を JIS X 0221 順に並べることも可能になります。 この場合、tounicode コードリファレンスとして、 Shift-JIS 漢字を UCS の符号位置に対応付けるサブルーチンを与える 必要があります。

level
適用される最大の照合レベルを指定します。照合レベルについて、詳細は後述。
  Level 1: 基本照合規則による照合
  Level 2: 第1照合属性まで考慮した照合(仮名の清濁)
  Level 3: 第2照合属性まで考慮した照合(文字の大小)
  Level 4: 第3照合属性まで考慮した照合(平仮名と片仮名)
  Level 5: 第4照合属性まで考慮した照合(全角と半角)

照合レベルは、1 から 5 までのいずれかの整数値で指定します。 省略時には、level 4 とします。

<注> 照合レベルが 0 から 4 でなくて、1ずつ大きいのは、 JIS X 4061 から見ると、直感的ではありません。 UTS #10, ISO/IEC DIS 14651 を参考にしています。 また、JIS X 4061 には、第4照合属性の規定はありません。 第4照合属性は、このモジュールによる追加事項です。

tounicode
漢字を UCS 順に並べるとき、kanji3 にした上で、 tounicode パラメータの値として、Shift-JIS の漢字から UCS の符号位置を返すサブルーチンのリファレンスを指定してください。

このようなサブルーチンは、Shift-JIS で符号化された 第1・第2水準の漢字(文字列)を UCS の符号位置 (0x4E000x9FFF の範囲の整数)に変換するものでなければなりません。

position_in_bytes
デフォルトでは、index メソッドは、結果を文字単位で返します。

このパラメータを真にすると、結果をバイト単位で返すようになります。

preprocess
これにコードリファレンスを与えると、ソートキーを作成する前に、 照合対象文字列を、与えられたコードリファレンスを用いて変換します。 つまり、コードリファレンスの返り値からソートキーを作成します。

upper_before_lower
デフォルトでは、小文字は大文字よりも前の順序になります。

このパラメータが真の場合、この順序が逆になります。

比較

$result = $Collator->cmp($a, $b)
返り値は以下のようになります。

$a$b より大きいときは 1$a$b に順序が等しいときは 0$a$b より小さいときは -1

$result = $Collator->eq($a, $b)
$result = $Collator->ne($a, $b)
$result = $Collator->gt($a, $b)
$result = $Collator->ge($a, $b)
$result = $Collator->lt($a, $b)
$result = $Collator->le($a, $b)
これらは、照合規則を適用して比較することを除き、 同名の演算子と同様な機能を持ちます。

ソート

$sortKey = $Collator->getSortKey($string)
ソートキーを返します。

ソートキーをバイナリ比較することで、 文字列の比較結果を得ることができます。

   $Collator->getSortKey($a) cmp $Collator->getSortKey($b)
      は、以下と等価です。
   $Collator->cmp($a, $b)

@sorted = $Collator->sort(@source)
「単純照合」によって文字列をソートします。

@sorted = $Collator->sortYomi(@source)
(読み列, 表記列) からなる配列リファレンスを 「読み・表記照合」によってソートします。

例えば、@source の要素は、['日本語', 'にほんご'] です。 その反対の ['にほんご', '日本語'] も使えますが、 (読み列, 表記列) という順序は変わりません。

「読み・表記照合」は2段階で比較をします。

例えば、以下のリストを「読み・表記照合」でソートするとしましょう。

['永田', 'ながた'], ['小山', 'おやま'], ['長田', 'おさだ'], ['長田', 'ながた'], ['小山', 'こやま'].

まず、読み列で順序付けします。 ('おさだ' < 'おやま' < 'こやま' < 'ながた');

次に、読み列が同じ文字列同士で、表記列を順序付けします。 (読みが 'ながた' のものでは、'永田' < '長田' です)

従って、結果は、以下のようになります: ['長田', 'おさだ'] < ['小山', 'おやま'] < ['小山', 'こやま'] < ['永田', 'ながた'] < ['長田', 'ながた'].

sample/yomi.txt も参照のこと。

@sorted = $Collator->sortDaihyo(@source)
(読み列, 表記列) からなる配列リファレンスを 「簡易代表読み照合」によってソートします。

注:このモジュールでは「基本代表読み照合」は実装されていません。

「簡易代表読み照合」は5段階で比較をします。

ここに、簡易代表読み照合でソートされたリストの例を示します。

  ['4面体', 'しめんたい'],
  ['2色性', 'にしょくせい'],
  ['4次元', 'よじげん'],
  ['6面体', 'ろくめんたい'],
  ['α崩壊', 'アルファほうかい'],
  ['Γ関数', 'ガンマかんすう'],
  ['β線',   'ベータせん'],
  ['Q値',   'キューち'],
  ['JIS', 'じす'],
  ['Perl',   'パール'],
  ['河西',   'かさい'],
  ['河合',   'かわい'],
  ['河田',   'かわだ'],
  ['河内',   'かわち'],
  ['河辺',   'かわべ'],
  ['角田',   'かくた'],
  ['角田',   'かどた'],
  ['関東',   'かんとう'],
  ['河内',   'こうち'],
  ['沢島',   'さわしま'],
  ['沢嶋',   'さわしま'],
  ['沢田',   'さわだ'],
  ['澤島',   'さわしま'],
  ['澤嶋',   'さわしま'],
  ['澤田',   'さわだ'],
  ['角田',   'つのだ'],
  ['土井',   'つちい'],
  ['土居',   'つちい'],
  ['土井',   'どい'],
  ['土居',   'どい'],

(1) 表記列の先頭の文字の文字クラスを比較する。

  数字 ('4面体') < 欧字記号 ('α崩壊') < ラテン ('JIS') < 漢字 ('関東').

(2) 読み列の先頭字を比較する。

  e.g. 'しめんたい' < 'にしょくせい' < 'よじげん' < 'ろくめんたい'.

(3) 表記列の先頭字を比較する。

  e.g. ('河西','河田',etc.) < ('角田','角田') < ('関東');
       ('沢島','沢嶋','沢田') < ('澤島','澤嶋','澤田').

(4) 読み列全体を比較する。

  e.g. ['河西', 'かさい'] < ['河合', 'かわい'] < ['河田', 'かわだ'];
       ['角田', 'かくた'] < ['角田', 'かどた'].

(5) 表記列全体を比較する。

  e.g. ['沢島', 'さわしま'] < ['沢嶋', 'さわしま'].

sample/daihyo.txt も参照。

部分文字列の検索

$position = $Collator->index($string, $substring)
($position, $length) = $Collator->index($string, $substring)
$substring$string の一部にマッチする場合、 スカラーコンテキストでは、マッチする部分の最初の出現位置を返します。 リストコンテキストでは、位置とマッチした部分の文字列長さからなる (2要素の)リストを返します。

注意 マッチした部分の長さは、$substring の長さと異なる可能性があります。

$substring$string のどこにもマッチしない場合、 スカラーコンテキストでは -1 を、リストコンテキストでは空リストを返します。

  use ShiftJIS::Collate;
  use ShiftJIS::String qw(substr);
  my $Col = ShiftJIS::Collate->new( level => $level );
  my $str = "* ひらがなとカタカナはレベル3では等しいかな。";
  my $sub = "かな";
  my $match;
  if (my @tmp = $Col->index($str, $sub)) {
    $match = substr($str, $tmp[0], $tmp[1]);
  }

If $level is 1, you get "がな"; if $level is 2 or 3, you get "カナ"; if $level is 4 or 5, you get "かな".

もし substr 関数が、Shift-JIS の文字単位で部分文字列を作れないなら、 position_in_bytes を真にしてください。


NOTE

照合レベル

照合レベルは、照合順序が決定するまで、順に考慮されます。

デフォルトでは、レベル 1 から 4 までが評価され、レベル 5 は無視されます (JIS X 4061 ではレベル 5 は規定されていません)。

Level 1: 基底文字による順序
文字クラスの順序は、以下の通り。
    1   スペース
    2   記述記号
    3   括弧記号
    4   学術記号
    5   一般記号
    6   単位記号
    7   アラビア数字
    8   欧字記号
    9   ラテンアルファベット
   10   仮名(平仮名と片仮名)
   11   漢字
   12   げた記号

アルファベットはアルファベット順に、仮名は五十音順に、漢字は JIS X 0208 の 区点順になる。

げた記号 ('〓', 0x81AC, U+3013) はいかなる文字よりも大きい(順序が最後)。

順序が定義されていない文字、例えば制御文字、罫線記号、未定義文字などは、 照合に際して、完全に無視される(ないのと同じ)。

Level 2: 清濁による順序
仮名では、清音文字、濁音文字、半濁音文字の順とする。 例えば、'か' < 'が'; 'は' < 'ば' < 'ぱ' の順。

Level 3: 文字の大小による順序。
ラテン文字では、小文字は、大文字よりも前の順序とする。

仮名では、長音記号、小文字、繰返し記号、大文字の順とする。 例えば、'あー' < 'あぁ' < 'あゝ' < 'ああ' の順。

Level 4: 用字系による順序
平仮名は、片仮名よりも前の順序とする。例えば 'あ' < 'ア' の順。

Level 5: 文字幅による順序
Halfwidth and Fullwidth Forms に属する文字は、 対応する通常の文字よりも後の順序とする。

なお、JIS X 4061 にはレベル 5 に相当する規定はありません。 Level 5 は、このモジュールによる拡張です。

漢字文字クラス

JIS X 4061 では、3つの漢字文字クラスが規定されています。 このモジュールは、そのうち、最小漢字文字クラスと基本漢字文字クラスを サポートしています。

最小漢字文字クラス
以下の5文字から構成されます:
    '〃' (0x8156, U+3003)
    '仝' (0x8157, U+4EDD)
    '々' (0x8158, U+3005)
    '〆' (0x8159, U+3006)
    '〇' (0x815A, U+3007)

'仝' 以外の漢字は、照合の際に無視されます。

基本漢字文字クラス
最小漢字文字クラスに、第1水準および第2水準の漢字を加えたものです。 第1水準および第2水準の漢字の順序は、JIS の区点位置の順になります。 JIS X 0208 に規定されない漢字は、照合の際に無視されます。

拡張漢字文字クラス
最小漢字文字クラスに、すべての CJK 統合漢字を加えたものです。 CJK 統合漢字の順序は、UCS の符号順になります。

長音記号と繰返し記号の置き換え

   文字     SJIS    UCS     文字名
   'ー'    0x815B  U+30FC  KATAKANA-HIRAGANA PROLONGED SOUND MARK
   'ー'     0xB0    U+FF70  HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
   'ゝ'    0x8154  U+309D  HIRAGANA ITERATION MARK
   'ゞ'    0x8155  U+309E  HIRAGANA VOICED ITERATION MARK
   'ヽ'    0x8152  U+30FD  KATAKANA ITERATION MARK
   'ヾ'    0x8153  U+30FE  KATAKANA VOICED ITERATION MARK
KATAKANA-HIRAGANA PROLONGED SOUND MARKs
長音記号(半角形を含む)は、前に仮名があれば、 対応する母音字または鼻音字(「あいうえおん」)に置き換えられます。
  'カー'   → 'カア'
  'びー'   → 'びイ'
  'きゃー' → 'きゃア'
  'ピュー' → 'ピュウ'
  'ンー'   → 'ンン'
  'んー'   → 'んン'

HIRAGANA- and KATAKANA ITERATION MARKs
繰返し記号(清音)は、前に仮名があれば、 対応する仮名(清音)に置き換えられます。
  'かゝ'   → 'かか'
  'ドゝ'   → 'ドと'
  'んゝ'   → 'んん'
  'カヽ'   → 'カカ'
  'ばヽ'   → 'ばハ'
  'プヽ'   → 'プフ'
  'ヴィヽ' → 'ヴィイ'
  'ピュゝ' → 'ピュゆ'

HIRAGANA- and KATAKANA VOICED ITERATION MARKs
繰返し記号(濁音)は、前に仮名があれば、 対応する仮名(濁音)に置き換えられます。
  'はゞ' → 'はば'
  'プゞ' → 'プぶ'
  'プヾ' → 'プブ'
  'こヾ' → 'こゴ'
  'ウヾ' → 'ウヴ'

置き換えのない場合
以上の場合を除き、置き換えは起こりません。

置き換えのない場合、長音記号および繰返し記号は、 他の仮名より後の順になります。

置き換えのない場合としては、例えば、 長音記号の前に CJK 統合漢字がある場合、 繰返し記号の前に数字がある場合、 'アヾ'('ア' には濁音はありません)があります。

照合順序の例
例えば照合対象文字列「パール」は、3つの照合要素を持ちます。すなわち、 「片仮名のパ」、「片仮名アで置き換えられた長音記号」、「片仮名ル」です。
   「パール」は基底文字列「パアル」に置き換えられます。
     レベル 1 では「はある」に等しい。
     レベル 2 では「ぱある」に等しく、「はある」よりも大きい。
     レベル 3 では「ぱーる」に等しく、「パアル」よりも小さい。
     レベル 4 では「ぱーる」よりも大きい。

処理系定義項目 [JIS X 4061, 6.2]

  (1) 文字の符号化方法: Shift-JIS.
  (2) 照合対象文字列の最大有効文字数:制限無し
  (3) 文字クラスの追加:なし
  (4) 文字の追加は以下の通りです。
      IDEOGRAPHIC SPACE を「スペース」文字クラスに追加。
      ACUTE ACCENT, GRAVE ACCENT, DIAERESIS, CIRCUMFLEX ACCENT
      を「記述記号」文字クラスに追加。
      APOSTROPHE, QUOTATION MARK を「括弧記号」文字クラスに追加。
      HYPHEN-MINUS を「学術記号」文字クラスに追加。
  (5) ラテンアルファベットにおけるマクロン付き及びサーカムフレックス付き文字
      は、サポートしません。
  (6) 選択した漢字文字クラス:最小漢字文字クラスおよび基本漢字文字クラス


作者

SADAHIRO Tomoyuki <SADAHIRO@cpan.org> 貞廣 知行

  Copyright(C) 2001-2007, SADAHIRO Tomoyuki. Japan. All rights reserved.
  This module is free software; you can redistribute it
  and/or modify it under the same terms as Perl itself.


参考

JIS X 4061:1996
日本語文字列照合順番

JIS X 0201:1997
7ビット及び8ビットの情報交換用符号化文字集合

JIS X 0208:1997
7ビット及び8ビットの2バイト情報交換用符号化漢字集合

JIS X 0221:1995
国際符号化文字集合 (UCS) ― 第1部 体系及び基本多言語面

日本工業標準調査会 (JISC)
http://www.jisc.go.jp/

日本規格協会 (JSA)
http://www.jsa.or.jp/

Unicode Collation Algorithm (UTS #10)
http://www.unicode.org/reports/tr10/

ISO/IEC DIS 14651
http://wwwold.dkuug.dk/jtc1/sc22/wg20/docs/projects#14651

the ShiftJIS::String manpage
the ShiftJIS::Regexp manpage