아래와 같이 특수 문자가 섞여 있는 문자열이 있습니다.
"São Paulo, Brazil. Wien, Österreich."
이런 문자열을 아래와 같이 알파벳으로 변경하고 싶다면 어떻게 해야 할까요?
"Sao Paulo, Brazil. Wien, Osterreich."
고민 없이 쉽게 할 수 있는 방법은 대상 문자를 찾아서 원하는 문자로 치환하는 방법입니다. 치환해야 할 문자 종류가 많지 않다면, 간단하게 적용할 수 있는 방법입니다.
그런데 치환 대상 문자의 개수가 1750개 이상이라면 어떻게 해야 할까요? 이럴 때 필요한 것이 Unicode Normalization(유니코드 정규화)입니다.
특수문자? combining characters?
위에서 특수문자라고 표현했던 문자는 유니코드에서 사용되는 Combining Characters(결합 문자)입니다. 문자에 Combining Mark(결합 문자)를 합하여 표현하는 방식으로 영어의 발음기호, 악센트, 베트남어, 독일어 등에서 사용합니다.
e + ´ = é
u + ¨ = ü
a(65) != ã(227) 그러나 a == ã
A의 유니코드 값은 65 , ̃의 유니코드 값은 771, 그래서 ã의 유니코드 227 값은 입니다. 유니코드 값 기준으로 보면 다르지만 데이터 처리 과정에서 동일하게 처리해야 하는 경우도 있습니다. 예를 들어 사용자의 이름을 São Paulo로 저장했습니다. 하지만 검색을 위해서는 São Paulo와 Sao Paulo가 모두 허용되어야 합니다. 이런 과정을 위해서 필요한 것이 유니코드 정규화입니다.
Golang에서 Unicode Normalization
Golang에서는 유니코드 정규화를 위해 golang blog에서 친절하게 가이드하고 있습니다.
결론
사용자에게서 제약 없는 문자를 입력받을 때는 유니코드 정규화를 고려해야 합니다. 한글, 영문자만 허용하다가, 세상 모든 단어를 입력 가능하게 바꾸니 이런 문제도 경험합니다.