それは常用漢字ですか?
概要
スカウトメールとか、広告のメールに担当者の名前がバーンと出てるようなメールありますよね。あれって一種の源氏名で、本当にそんな人は存在しないのではないかと常々思ってる訳なのですが、絶対にそんな人いない!と断言は出来ないのでもやっとしますよね。
もし人名に使われない漢字を使ってる名前でメールが送られてきたら、これは絶対に無い!って思えるのにな・・・
と思ったのがきっかけでした。人名に使える漢字は、「常用漢字」プラス「人名用漢字」で定義されています。
そう、今日は「常用漢字」を判定するライブラリを作った話をします(なぜこうなったのか・・・。
常用漢字とは?
常用漢字は、
一般の社会生活において現代の国語を書き表すための漢字使用の目安
として示されている漢字の集合です。最新は 平成22年内閣告示第2号 (2010年11月30日)として告示されているものです。
新聞、雑誌、放送、公文書などわたしたちが接する文書に含まれる漢字はだいたいこれに従って使われています。「だいたい」というところがミソで、従わなければいけなものではありません。しかし、読みやすさを優先したい場合、常用漢字に含まれない漢字を使うのは避けた方がよさそうです。
常用漢字の文字セット
常用漢字の文字セットがUnicodeのコードポイントで示されていればGoのunicode.RangeTableに変換して判定可能になります。しかし、示されているのは PDF文書 でこいつから該当漢字を抜き出すのはつらそうです。
さいわい文化庁のHPに 常用漢字表の音訓検索 があって、このページに一覧があるので、ここから文字を拾ってRangeTableに変換していきます。文字さえ拾えればテーブルに変換する作業は前にもやったことがある作業なので、そんなに手間でも無いです。勝った╭( ・ㅂ・)و ̑̑ グッ !
参考:https://zenn.dev/ikawaha/articles/20210116-ab1ac4a692ae8bb4d9cf
常用漢字表は得られたが
常用漢字表は得られましたが、このテーブルに文字が入っているか、そうでないかだけを判定すると漢字以外の文字(ひらがなとかカタカナとか記号とか)も弾かれてしまいます。やりたいのは、
漢字だったときに、それが常用漢字でない場合に知りたい
ということなので、漢字であるときだけ判定するような関数も用意しました。
func IsNotRegularUse(r rune) bool {
return unicode.Is(unicode.Han, r) && !unicode.Is(RegularUseRangeTable, r)
}
unicode.Han
は(だいたい)漢字です。漢字の時だけ常用漢字であるか判定して、常用漢字でなければ教えてくれます。
また、常用漢字でない漢字だけを見つけたら置き換える関数も用意しました。
replaced := ReplaceNotRegularUseAll("夜明け間際の𠮷野屋では", "■")
とすると常用漢字にない下側が長い𠮷
が置き換えられて "夜明け間際の■野屋では"
が得られます。
いくつかのバリエーションのために
常用漢字表はあくまで「目安」なので、用途によって調整して使われているそうです。 Wikipediaによれば、日本新聞協会新聞用語懇談会は下記の7文字を使用しないことに決めている そうです。そのような場合は個別に判定機を生成できるようにしていますので、許容しない漢字をセットしたカスタム判定機を用意できます。
'虞', '且', '遵', '朕', '但', '附', '又'
func TestDisallow(t *testing.T) {
d := NewRegularUseDiscriminator(Disallow([]rune{
'虞', '且', '遵', '朕', '但', '附', '又',
}...))
for _, v := range "虞且遵朕但附又" {
if got, want := d.IsNotRegularUse(v), true; got != want {
t.Errorf("d.IsNotRegularUse(%c) = %v, want %v", v, got, want)
}
}
}
逆に常用漢字外の文字も許容するようにオプションをセットすることも可能です(Allow
オプション)。
まとめ
なんでこんなことに手を出してしまったんだというお気持ちです。あとは人名用漢字の判定を作れば目的(?)を達成できそうです。
Happy hacking!
Discussion