🐘

旧字体と新字体の相互変換

に公開

旧字体とは

旧字体は当用漢字字体表(1949年)制定以前に使用されていた漢字の活字字体であり、康熙字典体に代表される。

1949年に制定された当用漢字字体表は、1981年の常用漢字表によって置き換えられた。現行の常用漢字表は、2010年に改訂されたものである。

しかし、旧字体の利用は完全に止まったわけではない。商号や商標、地名などでは、視覚的・歴史的価値を重んじて旧字体が引き続き用いられている例も多い。

次の画面は麻雀ゲームの天鳳というゲームで「国士無双」を和了した画面である。ここでは、視覚的インパクトを重視して、旧字体「國士無雙」が使われていることがわかる。

引用: https://note.com/kawauso16/n/n368202c62929

旧字体がアプリケーションに与える影響

旧字体は字形だけでなく、コードポイントが違うので別の文字として認識される。こうした問題は検索やレコメンドするときに問題になる可能性がある。

例えば、ECサイトで「桜」と検索したときに「櫻」を利用した商品がでてこなかったとしよう。「櫻」を商品名に利用した出展者は「予期しない動作」として運営者にクレームするかもしれない。

Unicodeにおける日本語の新旧字体変換の難しさ

Unicodeでは、1つのコードポイントに対して複数の字形を指定する手段として、異体字セレクタ(Ideographic Variation Selector, IVS) が導入されている。これにより、フォント依存ではない明示的な字形制御が可能である。これを利用できないか考えるのは自然である。

しかしながら、日本語における旧字体と新字体の関係は、異体字では解決できないケースが多い。なぜなら、旧字体と新字体が異なるコードポイントとして定義されていることが一般的だからだ。

例えば、「亞」(U+4E9E) の新字体は「亜」でありそのコードポイントは U+4E9Cである。

このような例では、異体字セレクタによって旧字体・新字体を切り替えることはできず、文字コードそのものを変換しない限り字形も変化しない。よって後述する対応表を使うのが望ましい。

常用漢字表を利用する

上記の背景から現実的に変換をするのであれば、常用漢字表を用いるのが最善策と思われる。幸いコードポイントを先人がまとめてくれているのでそれを利用すると良い。

https://github.com/ikawaha/kanji

もし、直接取得したいという場合は文化省から配布されているpdfを利用すること。
https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kijun/naikaku/kanji/

この表の常用漢字表の丸括弧を用いれば対応表を自作できる。

丸括弧に入れて添えたものは,いわゆる康熙字典体である。これは,明治以来行われてきた活字の字体とのつながりを示すために参考として添えたものであるが,著しい差異のないものは省いた。

PHPで旧字体と新字体の変換を実装

実装は str_replace関数を利用すれば容易にできる。他の言語でも同様の実装が可能。例えば、Pythonであれば str型のオブジェクトのメソッド translate() で実装できる。

<?php
class KanjiStyleMapper {
    public const OLD_STYLE = [
        '亞',
        // ...
        '灣',
    ];
    public const NEW_STYLE = [
        '亜',
        // ...
        '湾',
    ];
}

function replaceOldToNew(string $text): string {
    return str_replace(KanjiStyleMapper::OLD_STYLE, KanjiStyleMapper::NEW_STYLE, $text);
}

$input = "一晩で國士無雙二回もアガった";
$output = replaceOldToNew($input);
echo $output;  // 一晩で国士無双二回もアガった

なお、ここまでのコードは一部抜粋であり、完全なコードは以下のGistを参照すること。

https://gist.github.com/shunsock/d702bcbac5dc097b7db72582691b18ec

PHP Playground で挙動の確認をする

おわりに

このような話をするとAIにできないのかという話題がでてくると思われるが、「結論としてはできるが効率的ではない」が回答になる。推論にかかるお金と時間がもったいないので、上記のGistを参考にお手元の言語で実装してみてほしい。

なお、著者はGPT4が出て数ヶ月の時点で検証し、発表をしている。この時点 (2023年3月)でもAIはある程度新旧字体の変換ができていた。
https://logmi.jp/main/technology/328614

参照

Wikipedia "旧字体"
https://ja.wikipedia.org/wiki/旧字体#:~:text=旧字体��%8[…]E4��である。

昭和56年内閣告示第1号 "当用漢字字体表"
https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/series/21/pdf/kokugo_series_021_10.pdf

平成22年内閣告示第2号 "常用漢字表"
https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kijun/naikaku/kanji/

Wikipedia "康熙字典体"
https://ja.wikipedia.org/wiki/康熙字典

PHP公式ドキュメント "str_replace"
https://www.php.net/manual/en/function.str-replace.php

Python公式ドキュメント "str.translate"
https://docs.python.org/3/library/stdtypes.html#str.translate

(自著) PR TIMES開発者ブログ "新旧字体の表記ゆれを統一するために互換表を作成した話"
https://developers.prtimes.jp/2022/11/18/change_word_form/

Discussion