개발/Python

[파이썬] 유니코드 정규화

MinorMan 2022. 10. 9. 04:05
반응형

<질문>

파이썬에서 유니코드 문자열을 정규화하여 표현하는 데 사용할 수 있는 가장 단순한 유니코드 엔터티만 이해할 수 있도록 하는 표준 방법이 있습니까?

내 말은, 다음과 같은 시퀀스를 번역하는 것입니다.['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT'] 에게['LATIN SMALL LETTER A WITH ACUTE'] ?

문제가 어디에 있는지 확인하십시오.

>>> import unicodedata
>>> char = "á"
>>> len(char)
1
>>> [ unicodedata.name(c) for c in char ]
['LATIN SMALL LETTER A WITH ACUTE']

그러나 지금:

>>> char = "á"
>>> len(char)
2
>>> [ unicodedata.name(c) for c in char ]
['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT']

물론 모든 문자를 반복하고 수동 교체 등을 수행할 수 있지만 효율적이지 않으며 특수한 경우의 절반을 놓치고 실수를 범할 것이라고 확신합니다.


<답변1>

그만큼unicodedata 모듈은.normalize() function, NFC 형식으로 정규화하려고 합니다. 같은 것을 사용한 예U+0061 LATIN SMALL LETTER -U+0301 A COMBINING ACUTE ACCENT 조합과U+00E1 LATIN SMALL LETTER A WITH ACUTE 사용한 코드 포인트:

>>> print(ascii(unicodedata.normalize('NFC', '\u0061\u0301')))
'\xe1'
>>> print(ascii(unicodedata.normalize('NFD', '\u00e1')))
'a\u0301'

(나는 사용했다.ascii() function 여기에서 비ASCII 코드포인트가 이스케이프 구문을 사용하여 인쇄되도록 하여 차이점을 명확하게 합니다).

NFC 또는 'Normal Form Composed'는 구성된 문자를 반환하고 NFD, 'Normal Form Decomposed'는 분해, 결합된 문자를 제공합니다.

추가 NFKC 및 NFKD 양식은 호환성 코드 포인트를 다룹니다. 예를 들어U+2160 ROMAN NUMERAL ONE 정말 똑같다U+0049 LATIN CAPITAL LETTER I 그러나 별도로 취급하는 인코딩과 호환되도록 유니코드 표준에 존재합니다. NFKC 또는 NFKD 형식을 사용하면 문자를 구성하거나 분해하는 것 외에도 모든 '호환성' 문자가 표준 형식으로 바뀝니다.

다음은U+2167 ROMAN NUMERAL EIGHT 코드 포인트; NFKC 형식을 사용하여 이것을 ASCII 시퀀스로 바꿉니다.V 그리고I 문자:

>>> unicodedata.normalize('NFC', '\u2167')
'Ⅷ'
>>> unicodedata.normalize('NFKC', '\u2167')
'VIII'

구성 및 분해 형식이 교환 가능하다는 보장은 없습니다. 결합된 문자를 NFC 형식으로 정규화한 다음 결과를 다시 NFD 형식으로 변환해도 항상 동일한 문자 시퀀스가 나오는 것은 아닙니다. 유니코드 표준maintains a list of exceptions; 이 목록에 있는 문자는 구성할 수 있지만 여러 가지 이유로 결합된 형태로 다시 분해할 수는 없습니다. 에 대한 설명서도 참조하십시오.Composition Exclusion Table.


<답변2>

Yes, there is.

unicodedata.normalize(form, unistr)

네 가지 중 하나를 선택해야 합니다.normalization forms.

반응형