8

文字とそのすべての可能な分音記号のバリエーション (アクセントを区別しない) を正規表現と一致させようとしています。もちろん、私ができることは次のとおりです。

re.match(r"^[eēéěèȅêęëėẹẽĕȇȩę̋ḕḗḙḛḝė̄]$", "é")

しかし、それは一般的な解決策ではありません。この場合\pL、一致を特定の文字に減らすことはできませんe

4

1 に答える 1

20

望ましい目標を達成するための回避策は、最初にユニコードを使用てすべての分音記号を取り除き、次に通常の記号と一致させることです。e

re.match(r"^e$", unidecode("é"))

または、この単純化されたケースでは

unidecode("é") == "e"

unidecode-library に依存せず、unicode を保持し、より多くの制御を提供する別の解決策は、次のように分音記号を手動で削除することです。

unicodedata.normalize()を使用して、入力文字列を通常の形式 D (分解) に変換し、複合文字éが分解された形式e\u301(e + COMBINING ACUTE ACCENT)に変換されるようにします。

>>> input = "Héllô"
>>> input
'Héllô'
>>> normalized = unicodedata.normalize("NFKD", input)
>>> normalized
'He\u0301llo\u0302'

次に、カテゴリMark、Nonspacing (short Mn) に分類されるすべてのコードポイントを削除します。それらはすべて、幅自体がなく、前の文字を飾るだけの文字です。カテゴリを決定するには、 unicodedata.category()を使用します。

>>> stripped = "".join(c for c in normalized if unicodedata.category(c) != "Mn")
>>> stripped
'Hello'

結果は、上記の unidecode の例と同様に、正規表現マッチングのソースとして使用できます。関数として全体を次に示します。

def remove_diacritics(text):
    """
    Returns a string with all diacritics (aka non-spacing marks) removed.
    For example "Héllô" will become "Hello".
    Useful for comparing strings in an accent-insensitive fashion.
    """
    normalized = unicodedata.normalize("NFKD", text)
    return "".join(c for c in normalized if unicodedata.category(c) != "Mn")
于 2016-03-03T21:12:36.083 に答える