유니 코드 용어집
유니 코드는 방대하고 복잡한 주제입니다. 너무 깊이 들어가고 싶지는 않지만 빠른 용어집이 필요합니다.
- 코드 포인트 : 코드 포인트는 유니 코드의 기본 구성 요소이며, 코드 포인트는 의미에 매핑 된 정수일뿐입니다 . 정수 부분은 32 비트 (실제로는 24 비트)에 적합하며 그 의미는 문자, 분음 부호, 공백, 기호, 스마일리, 반쪽 플래그 등이 될 수 있습니다. 다음 부분은 오른쪽에서 왼쪽으로 읽습니다. "
- Grapheme Clusters : Grapheme Clusters는 의미 적으로 관련된 코드 포인트의 그룹입니다. 예를 들어 유니 코드의 플래그는 두 개의 코드 포인트를 연결하여 표시됩니다. 이 두 가지 각각은 따로 의미가 없지만 Grapheme Cluster에서 함께 연결되어 플래그를 나타냅니다. Grapheme Clusters는 일부 스크립트에서 문자를 분음 부호와 쌍을 이루는데도 사용됩니다.
이것이 유니 코드의 기본입니다. 대부분의 현대 언어의 경우 각 "문자"가 단일 코드 포인트에 매핑되기 때문에 코드 포인트와 Grapheme 클러스터 사이의 차이는 대체로 간과 될 수 있습니다 (일반적으로 사용되는 문자 + 분음 부호 조합에 대한 전용 악센트 형식이 있습니다). 그래도 스마일리, 깃발 등을 사용한다면 구별에주의를 기울여야 할 수도 있습니다.
UTF 입문서
그런 다음 일련의 유니 코드 코드 포인트를 인코딩해야합니다. 일반적인 인코딩은 UTF-8, UTF-16 및 UTF-32이며, 후자의 두 가지는 Little-Endian 및 Big-Endian 형식으로 존재하며 총 5 개의 공통 인코딩이 있습니다.
UTF-X에서 X는 코드 단위의 비트 크기이며 , 각 코드 포인트는 크기에 따라 하나 또는 여러 코드 단위로 표시됩니다.
- UTF-8 : 1-4 코드 단위,
- UTF-16 : 1 개 또는 2 개의 코드 단위,
- UTF-32 : 1 코드 단위.
std::string및 std::wstring.
std::wstring이식성에 관심이 있다면 사용하지 마십시오 ( wchar_tWindows에서는 16 비트 만 가능). 사용하는 std::u32string대신 (일명 std::basic_string<char32_t>).
- 메모리 내 표현 (
std::string또는 std::wstring)은 디스크상의 표현 (UTF-8, UTF-16 또는 UTF-32)과 독립적이므로 경계 (읽기 및 쓰기)에서 변환해야 할 준비를하십시오.
- 32 비트
wchar_t는 코드 단위가 전체 코드 포인트를 나타내도록 보장하지만 여전히 완전한 Grapheme 클러스터를 나타내지는 않습니다.
문자열을 읽거나 작성하는 경우 std::string또는 std::wstring.
슬라이싱과 다이 싱을 시작할 때 문제가 시작되면 (1) 코드 포인트 경계 (UTF-8 또는 UTF-16) 및 (2) Grapheme 클러스터 경계에주의를 기울여야합니다. 전자는 쉽게 처리 할 수 있고 후자는 유니 코드 인식 라이브러리를 사용해야합니다.
따기 std::string또는 std::u32string?
성능이 문제라면 std::string메모리 공간이 더 작기 때문에 성능이 더 좋아질 가능성이 높습니다 . 중국어를 많이 사용하면 거래가 달라질 수 있습니다. 항상 그렇듯이 프로필.
Grapheme Clusters가 문제가되지 않는다면 std::u32string일을 단순화하는 이점이 있습니다. 1 Code Unit- > 1 Code Point는 실수로 코드 포인트를 분리 할 수 없다는 의미이며 모든 std::basic_string작업 기능을 즉시 사용할 수 있습니다.
당신이 소프트웨어 복용과 인터페이스하는 경우 std::string또는 char*/ char const*다음에 충실 std::string앞뒤로 변환을 방지하기 위해. 그렇지 않으면 고통이 될 것입니다.
UTF-8 std::string.
UTF-8은 실제로 std::string.
UTF-8 인코딩이 자체 동기화되고 ASCII와 역 호환되기 때문에 대부분의 작업은 기본적으로 작동합니다.
코드 포인트가 인코딩되는 방식으로 인해 코드 포인트를 찾는 것은 실수로 다른 코드 포인트의 중간과 일치 할 수 없습니다.
str.find('\n') 공장,
str.find("...")1 바이트 단위로 일치하는 작업 ,
str.find_first_of("\r\n")ASCII 문자를 검색하는 경우 작동 합니다 .
유사하게, regex대부분은 즉시 작동합니다. 일련의 문자 ( "haha")는 단순히 일련의 바이트 ( "哈")이므로 기본 검색 패턴이 즉시 작동해야합니다.
그러나 [:alphanum:]정규식 버전 및 구현에 따라 유니 코드 문자와 일치 할 수도 있고 일치하지 않을 수도 있으므로 문자 클래스 (예 :)에주의하십시오 .
마찬가지로 비 ASCII "문자"에 repeater를 적용하는 것에주의 "哈?"하십시오. 마지막 바이트 만 선택 사항으로 간주 할 수 있습니다. 다음과 같은 경우 괄호를 사용하여 반복되는 바이트 시퀀스를 명확하게 설명 "(哈)?"합니다..
1 조회의 핵심 개념은 정규화와 데이터 정렬입니다. 이것은 모든 비교 작업에 영향을 미칩니다. std::string언어 또는 용도에 특정한 비교 규칙에 관계없이 항상 바이트별로 비교 (따라서 정렬)합니다. 전체 정규화 / 데이터 정렬을 처리해야하는 경우 ICU와 같은 완전한 유니 코드 라이브러리가 필요합니다.