K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

々・ゝなどの踊り字を展開する

01.7.3

々・ゝなどの踊り字を展開する

最終更新 2020-02-26 読了時間 2 分
まとめ
「時々」「人々」の「々」や、古い仮名遣いの「ゝ」「ヽ」などの踊り字(繰り返し記号)を、直前の文字に置き換えて「時時」「人人」のように展開します。1 文字ずつ走査しながら直前の文字を prev_char に覚えておき、踊り字に出会ったらそれを書き出すだけの純粋な Python 関数で、濁点付きの「ゞ」「ヾ」はコードポイントを 1 つ進めて「つ」から「づ」を作ります。「時々」で検索して「時時」を取り逃がすような、キーワードマッチの漏れを防ぎたいときに使います。

直感 #

「時々」「人々」などの踊り字は、人には読めてもプログラムには「時」と「々」という別々の 2 文字です。「人人」で部分一致検索をしても「人々」はヒットしませんし、文字単位の n-gram を作れば「々」という意味を持たない文字が特徴量に混ざります。すべて元の漢字や仮名に展開しておけば、形態素解析や単純な in によるフィルタでも漏れが減ります。やることは「踊り字を見たら直前の文字をもう 1 回書く」だけで、ひらがなの「ゞ」だけは「直前の文字に濁点を付けたもの」を書きます。

Python で展開する #

次のコードは、漢字の踊り字(々・〻)、ひらがなの踊り字(ゝ・ゞ)、カタカナの踊り字(ヽ・ヾ)の 3 グループを判定し、直前の文字(濁点付きなら 1 つ進めた文字)に置き換えて返します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def expand_iteration_marks(text: str) -> str:
    result = []
    prev_char = ""
    for ch in text:
        if ch in {"\u3005", "\u303B"} and prev_char:
            result.append(prev_char)
        elif ch in {"\u309D", "\u309E"} and prev_char:
            # ひらがなの繰り返し
            base = prev_char
            if ch == "\u309E":  # ゞ
                base = chr(ord(base) + 1)
            result.append(base)
        elif ch in {"\u30FD", "\u30FE"} and prev_char:
            base = prev_char
            if ch == "\u30FE":  # ヾ
                base = chr(ord(base) + 1)
            result.append(base)
        else:
            result.append(ch)
            prev_char = ch
    return "".join(result)

samples = [
    "時々のことなので人々にも共有する",
    "くつゝいた靴下",
    "サンバゝ←古い仮名遣い",
]

for s in samples:
    print(expand_iteration_marks(s))

実行結果の読み方 #

「時々」が「時時」、「人々」が「人人」になり、「くつゝいた」は「ゝ」が直前の「つ」に置き換わって「くつついた」になります。3 つ目の「サンバゝ」は「サンババ」です。展開後の文字列は人が読むには不自然ですが、検索キーや特徴量として使う内部表現としては「々」を含まないほうが扱いやすいので、表示用の元の列と展開後の列を分けて持つのが基本です。

使いどころと落とし穴 #

「ゝ」「ゞ」「ヽ」「ヾ」は歴史的仮名遣いの資料に多く、濁点の有無が文脈で決まる場合があるため、厳密な復元が必要なら +1 の機械的な変換ではなく読みの辞書で補正します。地名や固有名詞に使われる「々」は必ずしも同じ漢字の繰り返しとは限りません。「佐々木」をこの関数に通すと「佐佐木」になり、戸籍や顧客台帳の表記とは一致しなくなります。信頼できる正規化には、人名・地名の辞書やドメイン知識と組み合わせ、固有名詞の列には適用しないといった運用ルールを決めておきます。