본문 바로가기

코딩코오딩

[Swift] String - #6 Unicode


유니코드 문자열을 파일에 쓸 때 유니코드 스칼라는 몇 가지 유니코드 인코딩 형식(UTF-8, UTF-16, UTF-32)으로 인코딩 된다.

각 인코딩 형식은 code unit이라는 작은 덩어리(chunk)로 인코딩 된다.

 

Swift는 문자열의 Unicode 표현에 접근하기 위한 몇 가지 방법을 제공한다. for-in loop 구문을 사용하여 문자열을 interator 할 수 있고, 유니코드 확장 문자소 클러스터의 개별 Character에 접근할 수도 있다.

 

UTF-8 표현

String의 utf8 프로퍼티를 반복해서 UTF-8의 표현에 접근할 수 있다. 이 프로퍼티는 String.UTF8View 타입이고 unsigned 8-bit(UInt8) 값의 collection이다.

let dogString = "Dog‼🐶"
for codeUnit in dogString.utf8 {
    print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 226 128 188 240 159 144 182 "

위 예제에서 첫 번째 세 글자는 D, o, g는 codeUnit value(68, 111, 103)을 가지고 이 UTF-8의 표현은 ASCII 표현과 동일하다. 

그 다음 DOUBLE EXCLAMATION MARK(‼)는 codeUnit value(226, 128, 188)으로 표현된다.

마지막 4바이트는 DOG FACE(🐶)는 codeUnit values (240, 159, 144, 182)으로 표현된다.

 

UTF-16 표현

String의 utf16 프로퍼티를 반복해서 UTF-16의 표현에 접근할 수 있다. 이 프로퍼티는 String.UTF16View 타입이고 unsigned 16-bit(UInt16)값의 collection이다.

for codeUnit in dogString.utf16 {
    print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 55357 56374 "

앞의 세글자 D, o, g는 UTF-8과 동일하며, 네 번째 문자(DOUBLE EXCLAMATION MARK ‼)는 codeUnit value(8252) 값을 갖으며 이 값을 16진수 값(U+203C)과 동일하다. 

마지막 문자 DOG FACE(🐶)는 UTF-16의 표현 방식에 따라 codeUnit values (55357 and 56374)으로 UTF-16 surrogate pair로 표현된다.

 

 

유니코드 Scalar 표현

String의 유니코드 Scalar접근 방법은 unicodeScalars 프로퍼티를 통해서 가능하다. 이 프로퍼티는 UnicodeScalarView 타입이고, UnicodeScalar타입의 값의 collection이다.

 

각 UnicodeScalar는 value 프로퍼티를 통해 21-bit 값을 리턴하고 이 프로퍼티는 Uint32 타입이다.

for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 128054 "

앞 세 글자 D, o, g, 는 UnicodeScalar values(68, 111, 103, 8252)로 표현되고, 마지막 다섯 번째 DOG FACE(🐶)는 유니코드 스칼라 U+1F436의 십진수 표현인 128054가 된다.

 

UnicodeScalar 값은 새로운 String을 구성하는 데 사용할 수 있다.

 

인코딩 형식에서의 Index 처리

String에서의 구한 index는 utf-8이나 uft-16 인코딩 표현에서도 사용할 수 있다.

 

아래 그림과 같이 String의 첫 번째 공백문자 index인 firstSpace를 utf8 인코딩 형식에서도 그대로 사용하여 Array를 출력하고 있다.

반대의 경우인 utf-8 인코딩에서 얻은 index는 String에서 바로 사용하면 정확한 문자의 위치를 나타낼 수 없다.

따라서 samePosition(in:)를 사용해서 원래 String에서의 index를 구해야 한다.


참고 문서

https://ko.wikipedia.org/wiki/UTF-16

https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html

https://developer.apple.com/documentation/swift/string