名称

ShiftJIS::String - Shift-JIS 文字列操作関数


概要

  use ShiftJIS::String;
  ShiftJIS::String::substr($str, ShiftJIS::String::index($str, $substr));


このPODについて

このPODは、Shift-JISで書かれています。

'' が HIRAGANA LETTER A に見えますか ? また、'\' が REVERSE SOLIDUS ではなく YEN SIGN に見えますか ? さもなければフォントを正しいものに交換した方がよいでしょう。 (あるいは POD が変な変換をされたのかも知れません。)


詳細

このモジュールは、Shift-JIS の文字列を扱うのに有用であろう 組み込み関数に類似した関数を提供します。


関数

文字列が正しいかどうかの確認

issjis(LIST)
引数リストのすべての文字列が Shift-JIS として正しいか否かの真偽値を返します。

LIST が一つ以上の不正な文字列を含んでいる場合、偽を返します。

文字列の長さ

length(STRING)
文字単位の長さを返します。

逆順

strrev(STRING)
文字が逆順になった文字列を返します。

検索

index(STRING, SUBSTR)
index(STRING, SUBSTR, POSITION)
POSITION の位置またはそれ以降で、STRINGSUBSTR の最初の出現位置を返します。

POSITION を省略した場合は、文字列の先頭から探します。

部分文字列が見つからない時は -1 を返します。

rindex(STRING, SUBSTR)
rindex(STRING, SUBSTR, POSITION)
STRING 中、SUBSTR の最後の出現位置を返します。 POSITION を決めた時はその位置またはそれ以前で最後の出現位置を返します。

部分文字列が見つからない時は -1 を返します。

strspn(STRING, SEARCHLIST)
SEARCHLIST に含まれない任意の文字の最初の出現位置を返します。

STRINGSEARCHLIST 中の文字のみからなる場合は、 返り値は STRING の長さに等しくなります。

SEARCHLIST に直接文字範囲を使うことはできませんが、 関数 mkrange() を利用できるでしょう。

  strspn("+0.12345*12", "+-.0123456789");
  # 8 を返す('*' の位置)

strcspn(STRING, SEARCHLIST)
SEARCHLIST に含まれる任意の文字の最初の出現位置を返します。

STRINGSEARCHLIST 中のどの文字も含まない場合は、 返り値は STRING の長さに等しくなります。

SEARCHLIST に直接文字範囲を使うことはできませんが、 関数 mkrange() を利用できるでしょう。

  strcspn("Perlは面白い。", "赤青黄白黒");
  # 6 を返す('白' の位置)

rspan(STRING, SEARCHLIST)
SEARCHLIST に含まれない任意の文字の最後の出現位置を調べます。

そのような文字が見つかった場合には、その文字の次の位置を返します。 さもなければ(STRING のすべての文字が SEARCHLIST に含まれる場合)、 文字列の最初の位置として、0 を返します。

SEARCHLIST に直接文字範囲を使うことはできませんが、 関数 mkrange() を利用できるでしょう。

  rspan('+0123456789*+!', '*+!#$%');
  # 11 を返す('9' の次の '*' の位置)

rcspan(STRING, SEARCHLIST)
SEARCHLIST に含まれる任意の文字の最後の出現位置を調べます。

そのような文字が見つかった場合には、その文字の次の位置を返します。 さもなければ(STRING のどの文字も SEARCHLIST に含まれない場合)、 文字列の最初の位置として、0 を返します。

SEARCHLIST に直接文字範囲を使うことはできませんが、 関数 mkrange() を利用できるでしょう。

  rcspan("Perlは面白い。", "赤青黄白黒");
  # 7 を返す('白' の次の 'い' の位置)
  rcspan('ABCあいうXYZ', "あいうえお");
  # 6 を返す('う' の次の 'X' の位置)

文字列の前後の余分な文字の除去

trim(STRING)
trim(STRING, SEARCHLIST)
trim(STRING, SEARCHLIST, USE_COMPLEMENT)
STRING の先頭および末尾から、SEARCHLIST に含まれる文字を除去して その結果を返します。 ただし、USE_COMPLEMENT に真の値を与えた場合、逆に、 SEARCHLIST含まれない文字を除去します。

SEARCHLIST を省略した場合(または未定義値の場合)、 SEARCHLIST として、以下の空白類文字のリストを用います。 すなわち、"\t", "\n", "\r", "\f", "\x20"(空白), および "\x81\x40"(和字間隔)。

SEARCHLIST に直接文字範囲を使うことはできませんが、 trim($string, mkrange("\x00-\x20")) のように 関数 mkrange() を利用できるでしょう。

ltrim(STRING)
ltrim(STRING, SEARCHLIST)
ltrim(STRING, SEARCHLIST, USE_COMPLEMENT)
STRING の先頭から、SEARCHLIST に含まれる文字を除去して その結果を返します。 ただし、USE_COMPLEMENT に真の値を与えた場合、逆に、 SEARCHLIST含まれない文字を除去します。

SEARCHLIST に直接文字範囲を使うことはできませんが、 関数 mkrange() を利用できるでしょう。

rtrim(STRING)
rtrim(STRING, SEARCHLIST)
rtrim(STRING, SEARCHLIST, USE_COMPLEMENT)
STRING の末尾から、SEARCHLIST に含まれる文字を除去して その結果を返します。 ただし、USE_COMPLEMENT に真の値を与えた場合、逆に、 SEARCHLIST含まれない文字を除去します。

SEARCHLIST に直接文字範囲を使うことはできませんが、 関数 mkrange() を利用できるでしょう。

部分文字列

substr(STRING or SCALAR REF, OFFSET)
substr(STRING or SCALAR REF, OFFSET, LENGTH)
substr(SCALAR, OFFSET, LENGTH, REPLACEMENT)
組み込みの substr と同様ですが Shift-JIS 文字列に対して働きます。

第4引数として REPLACEMENT を渡した場合は、 SCALAR のその部分を置換して、その部分の元の部分文字列を返します。

以下のように、第1引数にスカラー変数へのリファレンスを使うと、 左辺値リファレンスを利用することができます。

    ${ &substr(\$str,$off,$len) } = $replace;
        は、CORE の
    CORE::substr($str,$off,$len) = $replace;
        のように働きます。

返り値の左辺値は(Perl組み込みの機能による部分文字列そのままに なっていますから、)Shift-JISに対応していません。従って、 2度目の代入や変更では期待通りの結果にならない可能性があります。

よくわからなければ、とにかく代入の前に左辺値を取得するのがよいでしょう。

    $str = "0123456789";
    $lval  = &substr(\$str,3,1);
    $$lval = "あい";
    $lval  = &substr(\$str,3,1); # もう一度左辺値を取得する。
    $$lval = "a";
    # $str is "012aい456789".

分割

strsplit(SEPARATOR, STRING)
strsplit(SEPARATOR, STRING, LIMIT)
この関数は組み込みの split のように働きますが、正規表現ではなくて、 SEPARATOR 文字列による分割を行います。 リストコンテキスト以外では、見つかったフィールドの数を返すのみです。 分割結果を @_ 配列に格納しません。
  strsplit('||', '||あいうえお||パピプペポ||01234||');
  # ('', 'あいうえお', 'パピプペポ', '01234')
  strsplit('/', 'Perl/駱駝/Camel');
  # ('Perl', '駱駝', 'Camel')

SEPARATOR として空文字列を用いた場合は、文字に分割します。 (CORE::split //, STRING, LIMIT と同様。)

  strsplit('', 'This is Perl.', 7);
  # ('T', 'h', 'i', 's', ' ', 'i',  's Perl.')

SEPARATOR として未定義値を用いた場合は、 空白類文字(和字間隔を含む)で分割します。 先頭から続く空白類文字は、フィールドを作りません。 (CORE::split ' ', STRING, LIMIT と同様。)

  strsplit(undef, '   This  is   Perl.');
  # ('This', 'is', 'Perl.')

比較

strcmp(LEFT-STRING, RIGHT-STRING)
返り値は、1 (LEFT-STRINGRIGHT-STRING より大きい時) か 0 (LEFT-STRINGRIGHT-STRING に等しい時) か -1 (LEFT-STRINGRIGHT-STRING より小さい時) になります。

文字順は大まかに言って、次のリストに示すようになります。

    JIS X 0201 ラテン文字,JIS X 0201 片仮名,JIS X 0208 漢字 (全角)。

例えば、 0x41 ('A') は 0xB1 ('ア') より小さい。 0xB1 ('ア') は 0x8341 ('ア') より小さい。 0x8341 ('ア') は 0x8383 ('ャ') より小さい。 0x8383 ('ャ') は 0x83B1 ('Τ' ギリシア大文字タウ) より小さい。

注意! 第二例と第四例の比較からわかるように、 バイト "\xB1" は第一バイトとしては "\x83" より小さいが、 第二バイトとしては大きくなります。 簡単に言えばバイナリ比較は Shift-JIS 文字順ではうまくいきません。

strEQ(LEFT-STRING, RIGHT-STRING)
LEFT-STRINGRIGHT-STRING に等しいかどうかの真偽値を返します。

注: strEQ は組み込みの eq 演算子と等価です。

strNE(LEFT-STRING, RIGHT-STRING)
LEFT-STRINGRIGHT-STRING に等しくないかどうかの真偽値を返します。

注: strNE は組み込みの ne 演算子と等価です。

strLT(LEFT-STRING, RIGHT-STRING)
LEFT-STRINGRIGHT-STRING より小さいかどうかの真偽値を返します。

strLE(LEFT-STRING, RIGHT-STRING)
LEFT-STRINGRIGHT-STRING より小さいまたは等しいか どうかの真偽値を返します。

strGT(LEFT-STRING, RIGHT-STRING)
LEFT-STRINGRIGHT-STRING より大きいかどうかの真偽値を返します。

strGE(LEFT-STRING, RIGHT-STRING)
LEFT-STRINGRIGHT-STRING より大きいまたは等しいか どうかの真偽値を返します。

strxfrm(STRING)
組み込みの cmp 演算子でバイナリ比較を行えるような 文字列に変換したものを返します。 (C 言語の同名関数と異なり、変換後の文字列の長さを返すのではありません。)

すなわち、あなたの Perl の cmp 演算子が Perl 以外のロカールを使用しない限り、 strxfrm($a) cmp strxfrm($b)strcmp($a, $b) と等価になります。

文字範囲

mkrange(EXPR, EXPR)
与えられた文字範囲を解釈して得られる文字リスト (リストコンテキスト以外では文字列に連結したもの)を返します。

文字範囲は '-' (HYPHEN-MINUS) で表わします。 エスケープした '\-' および '\\' はそれぞれ、 リテラルの '-' および '\' の代わりに用いられます。 最初または最後のハイフンはやはりハイフンそのものとして解釈されます。

例えば、mkrange('+\-0-9a-fA-F') は、 ('+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F') を、 そして scalar mkrange('か-ご')'かがきぎくぐけげこご' を返します。.

Shift-JIS 文字の順序は以下のとおりです。 0x00 .. 0x7F, 0xA1 .. 0xDF, 0x8140 .. 0x9FFC, 0xE040 .. 0xFCFC. だから、mkrange('亜-腕') は、第一水準の漢字すべてのリストを返します。

第二引数に真の値を渡した場合、'9-0''Z-A' のような 逆順の文字範囲を使えるようになります(返り値も逆順になります)。 そうでない場合、逆順の範囲があると croak されます(致命的エラー)。

文字の変換

strtr(STRING or SCALAR REF, SEARCHLIST, REPLACEMENTLIST)
strtr(STRING or SCALAR REF, SEARCHLIST, REPLACEMENTLIST, MODIFIER)
strtr(STRING or SCALAR REF, SEARCHLIST, REPLACEMENTLIST, MODIFIER, PATTERN)
strtr(STRING or SCALAR REF, SEARCHLIST, REPLACEMENTLIST, MODIFIER, PATTERN, TOPATTERN)
SEARCHLIST 中の文字のすべてを REPLACEMENTLIST 中に示された 対応する文字に変換します。

第一引数としてスカラー変数へのリファレンスを用いると、 スカラー変数内の文字列を変更して、 変換または削除された文字の数を返します。 それ以外の場合、元の文字列を変更することなく、変換後の文字列を返します。

  $str = "なんといおうか";
  print strtr(\$str,"あいうえお", "アイウエオ"), "  ", $str;
  # 出力: 3  なんとイオウか
  $str = "後門の狼。";
  print strtr($str,"後狼。", "前虎、"), $str;
  # 出力: 前門の虎、後門の狼。

SEARCHLIST および REPLACEMENTLIST

"ぁ-お" のような文字範囲(内部的に mkrange() を使用)を 用いることができます)。

REPLACEMENTLIST が空文字列の場合、SEARCHLIST で代用します。

REPLACEMENTLISTSEARCHLIST より短い場合、 REPLACEMENTLIST の最後文字が十分な長さまで用いられます。 (しかし 'd' 修飾子を用いた場合を除きます。)

  strtr(\$str, 'ぁ-んァ-ヶヲ-゚', '#');
    # すべての仮名文字を '#' に変換します。

MODIFIER

    c   SEARCHLIST の補集合を用います。
    d   C<SEARCHLIST> に含まれるが C<REPLACEMENTLIST> にない文字を削除します。
    s   同じ変換文字が連続した場合にひとつにまとめます。
    h   文字の出現頻度のハッシュ(またはそのリファレンス)を返します。
    R   文字範囲を使用しません。
    r   逆順の文字範囲を使えるようにします。
    o   変換表を内部的にキャッシュします。
  strtr(\$str, 'ぁ-んァ-ヶヲ-゚', '');
    # $str 中の仮名文字の数を数えます。
  $onlykana = strtr($str, 'ぁ-んァ-ヶヲ-゚', '', 'cd');
    # 仮名以外の文字を削除します。
  strtr(\$str, " \x81\x40\n\r\t\f", '', 'd');
    # 和字間隔を含む空白類文字を削除します。
  strtr("おかかうめぼし ちちとはは", 'ぁ-ん', '', 's');
    # 出力: おかうめぼし ちとは
  strtr("条件演算子の使いすぎは見苦しい", 'ぁ-ん', '#', 'cs');
    # 出力: #の#いすぎは#しい

'h' 修飾子を用いると、第一引数が文字列かリファレンスかに拘らず、 文字の出現頻度を、文字がキー、回数が値となるハッシュで返します。 スカラーコンテキストではハッシュリファレンスで返します。 同時に変更後の文字列を得たければ、第一引数としてリファレンスを渡し、 そのリファレンスの内容を変更させるようにしてください。

  %hist_kana = strtr('日本語のカタカナ', 'ぁ-んァ-ヶヲ-゚', '', 'h');
    # 仮名の出現頻度を調べます。
    # 返却値は ('の' => 1, 'カ' => 2, 'タ' => 1, 'ナ' => 1),
    # ただし、ハッシュのキーの順序は、こうなるとは限りません。

'R' 修飾子を用いると、'-' はメタ文字ではなく、 CORE:: の tr''' 中のように、ハイフンそのものとみなします。 SEARCHLISTREPLACEMENTLISTの中に、'-''\' も 含まれていないなら、'R' 修飾子の有無は実行結果に影響を与えませんが、 'R' 修飾子を指定すると、内部的には、範囲を解釈するための処理が 明示的に省略されます。

  strtr("90 - 32 = 58", "0-9", "A-J");
    # 出力: "JA - DC = FI"
  strtr("90 - 32 = 58", "0-9", "A-J", "R");
    # 出力: "JA - 32 = 58"
    # cf. ($str = "90 - 32 = 58") =~ tr'0-9'A-J';
    # '0' から 'A' に、'-' から '-' に、'9' から 'J' に。

'r' 修飾子を用いると、逆順の文字範囲が使えるようになります。 例えば、strtr($str, "0-9", "9-0", "r")strtr($str, "0123456789", "9876543210") と等価です。

  strtr($text, '亜-腕', '腕-亜', "r");
    # テキストが壊れたように見えるかも知れません。

PATTERN および TOPATTERN

PATTERN および TOPATTERN を用いると、複数文字からなる部分文字列を 単位とした変換を行うことができます。

四個の引数で関数を呼ぶと、SEARCHLISTREPLACEMENTLIST, および STRING は文字単位に分解されます。

五個の引数を渡すと SEARCHLISTREPLACEMENTLIST,および STRING 中の PATTERN にマッチする部分は変換の単位と見なされます。

PATTERNTOPATTERN との両方を渡すと、 SEARCHLISTSTRING 中の PATTERN にマッチする部分と、 REPLACEMENTLIST 中の TOPATTERN にマッチする部分 は変換の単位と見なされます。

  print strtr(
    "Caesar Aether Goethe",
    "aeoeueAeOeUe",
    "&auml;&ouml;&ouml;&Auml;&Ouml;&Uuml;",
    "",
    "[aouAOU]e",
    "&[aouAOU]uml;");
  # 出力: C&auml;sar &Auml;ther G&ouml;the

無名配列による LISTS

PATTERNTOPATTERN を渡す代わりに、以下に示すように、 SEARCHLIST および/または REPLACEMENTLIST として 無名配列を用いることができます。

  print strtr(
    "Caesar Aether Goethe",
    [qw/ae oe ue Ae Oe Ue/],
    [qw/&auml; &ouml; &ouml; &Auml; &Ouml; &Uuml;/]
  );

変換表のキャッシュ

'o' 修飾子を用いると、変換表が内部的にキャッシュされます。

例えば、

  foreach (@hiragana_strings) {
      print strtr($_, 'ぁ-ん', 'ァ-ン', 'o');
  }
  # 片仮名で出力される。

は、次のようにするのと、同じ位の効率があります。

  $hiragana_to_katakana = trclosure('ぁ-ん', 'ァ-ン');
  foreach (@hiragana_strings) {
      print &$hiragana_to_katakana($_);
  }

どちらでも好きな方を用いればいいでしょう。

'o' 修飾子なしでは、

  foreach (@hiragana_strings) {
      print strtr($_, 'ぁ-ん', 'ァ-ン');
  }

はとても遅くなるでしょう。なぜなら、変換表を 呼び出しの度に作成するからです。

変換のクロージャの生成

trclosure(SEARCHLIST, REPLACEMENTLIST)
trclosure(SEARCHLIST, REPLACEMENTLIST, MODIFIER)
trclosure(SEARCHLIST, REPLACEMENTLIST, MODIFIER, PATTERN)
trclosure(SEARCHLIST, REPLACEMENTLIST, MODIFIER, PATTERN, TOPATTERN)
文字列を変換するためのクロージャを返します。 返り値は単なるコードリファレンス(無名サブルーチン)であって、 ブレスされたオブジェクトではありません。

このコードリファレンスを使えば、変換対応を示すパラメータリストを 呼び出しのたびに渡す必要がありません。

  my $digit_tr = trclosure("1234567890-", "一二三四五六七八九〇−");
  print &$digit_tr ("TEL :0124-45-6789\n"); # perl 5.003 でも ok
  print $digit_tr->("FAX :0124-51-5368\n"); # perl 5.004 以降
  # 出力:
  # TEL :〇一二四−四五−六七八九
  # FAX :〇一二四−五一−五三六八

trclosure() により作られたクロージャの機能は strtr() のそれと同様です。 実のところ、strtr() は内部的に trclosure() を呼んで、 返却値のクロージャを使っています。

アルファベットの大文字・小文字

toupper(STRING)
toupper(SCALAR REF)
STRING を大文字化した文字列を返します。 半角ラテン文字 a-z から A-Z の変換のみを行います。

第一引数としてスカラー変数へのリファレンスを渡すと、 リファレンスされた文字列が変換されて、 変換された文字の数が返されます。

tolower(STRING)
tolower(SCALAR REF)
STRING を小文字化した文字列を返します。 半角ラテン文字 A-Z から a-z の変換のみを行います。

第一引数としてスカラー変数へのリファレンスを渡すと、 リファレンスされた文字列が変換されて、 変換された文字の数が返されます。

平仮名・片仮名の変換

第一引数としてスカラー変数へのリファレンスを渡すと、 リファレンスされた文字列が変換されて、 変換された文字の数が返されます。 そうでない場合、変換後の文字列が返され、 元の文字列に影響はありません。

注意
kanaH2Z(STRING)
kanaH2Z(SCALAR REF)
「半角カタカナ」を「カタカナ」に変換します。「ひらがな」は変換しません。

kataH2Z(STRING)
kataH2Z(SCALAR REF)
「半角カタカナ」を「カタカナ」に変換します。「ひらがな」は変換しません。

注: kataH2ZkanaH2Z の別名であり、機能に変わりはありません。

hiraH2Z(STRING)
hiraH2Z(SCALAR REF)
「半角カタカナ」を「ひらがな」に変換します。「カタカナ」は変換しません。

kataZ2H(STRING)
kataZ2H(SCALAR REF)
「カタカナ」を「半角カタカナ」に変換します。「ひらがな」は変換しません。

kanaZ2H(STRING)
kanaZ2H(SCALAR REF)
「ひらがな」および「カタカナ」をそれぞれ「半角カタカナ」に変換します。

hiraZ2H(STRING)
hiraZ2H(SCALAR REF)
「ひらがな」を「半角カタカナ」に変換します。「カタカナ」は変換しません。

hiXka(STRING)
hiXka(SCALAR REF)
「ひらがな」を「カタカナ」に、「カタカナ」を「ひらがな」に 一度に変換します。「半角カタカナ」は変換しません。

hi2ka(STRING)
hi2ka(SCALAR REF)
「ひらがな」を「カタカナ」に変換します。「半角カタカナ」は変換しません。

ka2hi(STRING)
ka2hi(SCALAR REF)
「カタカナ」を「ひらがな」に変換します。「半角カタカナ」は変換しません。

空白類文字の変換

第一引数としてスカラー変数へのリファレンスを渡すと、 リファレンスされた文字列が変換されて、 変換された文字の数が返されます。 そうでない場合、変換後の文字列が返され、 元の文字列に影響はありません。

spaceH2Z(STRING)
spaceH2Z(SCALAR REF)
文字列中の "\x20"(スペース)を "\x81\x40"(和字間隔)に変換します。

spaceZ2H(STRING)
spaceZ2H(SCALAR REF)
文字列中の "\x81\x40"(和字間隔)を "\x20"(スペース)に変換します。


注意事項

このモジュールでは正しい Shift-JIS 文字列の文字は 以下の正規表現にマッチしなければなりません。

   [\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]

外部リソースの文字列は、それが正しい Shift-JIS 文字列であると 分かっている場合を除いて issjis() を用いて確認すべきです。

正しくない Shift-JIS 文字列を使うと変な結果になることがあります。 (正しくない Shift-JIS 文字列を使った場合、どんな結果になるか、 何も決まっていませんので、何も期待してはいけません。)

Shift-JIS の二バイト文字の中には、第二バイトが [\x40-\x7E]、すなわち

   @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

であるものがあります。

Perl の構文解析では、このようなバイトについて 特別な処理はされていませんので、問題が発生することがあります。 例えば、リテラル "表" は致命的エラーを引き起こします。 なぜなら、第二バイトの 0x5C が閉じクォートをエスケープするからです。

外部のファイル等から読み出した場合は、この問題は起こりませんが、 スクリプトを Shift-JIS で書く時には十分な注意が必要です。

Shift-JISのリテラル文字列を作るためには、 シングルクォート風のヒアドク(<< '')や、 メタ文字 \xhh を使うほうがよいでしょう。

Shift-JIS の第二バイトに出て来ないASCII図形文字([\x21-\x3F])は 以下の通り。

   !"#$%&'()*+,-./0123456789:;<=>?

クォート風演算子のデリミタとしては、これを使うとよいかもしれません。


バグ

このモジュールでは $[ はいつも 0 であって、1 にならないと考えています。


著者

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.


関連モジュール

the ShiftJIS::Regexp manpage
the ShiftJIS::Collate manpage