2015-07-08 21 views
6

Ví dụ sau đây được lấy từ Strings and Characters documentation:Làm thế nào để chuyển đổi cặp đại diện cho Unicode vô hướng trong Swift

enter image description here

Các giá trị 55357 (U+D83D trong hex) và 56374 (U+DC36 trong hex) là cặp thay thế tạo thành vô hướng Unicode U+1F436, là ký tự DOG FACE. Có cách nào để đi theo hướng khác không? Đó là, tôi có thể chuyển đổi một cặp thay thế thành một vô hướng?

tôi đã cố gắng

let myChar: Character = "\u{D83D}\u{DC36}" 

nhưng tôi nhận được một thông báo lỗi "Invalid Unicode vô hướng".

This Objective C answerthis project dường như là giải pháp tùy chỉnh, nhưng có bất kỳ thứ gì được tích hợp vào Swift (đặc biệt là Swift 2.0+) không?

+0

Chỉ định điểm mã trực tiếp: '\ u {1F436}'. Có một ví dụ trong tài liệu bạn liên kết đến 'let sparklingHeart =" \ u {1F496} "//, vô hướng Unicode U + 1F496' ​​ – nhahtdh

+2

Nếu tôi không biết điểm mã đầy đủ thì sao? Đó là, nếu tôi chỉ biết các cặp thay thế? – Suragch

+0

'Chuỗi' có phương thức' init? (_ Utf16: String.UTF16View) ', nhưng tôi chưa tìm thấy cách tạo * một' String.UTF16View' từ một mảng đã cho. - Một câu hỏi tương tự (với các giải pháp khả thi) là ở đây: [Có cách nào để tạo một Chuỗi từ mảng utf16 nhanh không?] (Http://stackoverflow.com/questions/24542170/is-there-a-way-to -create-a-string-from-utf16-array-in-swift). –

Trả lời

1

Với một chuỗi các UTF-16 đơn vị mã (tức là số 16-bit, chẳng hạn như bạn nhận được từ String.utf16 hay chỉ là một mảng các số), bạn có thể sử dụng các loại UTF16decode phương pháp của mình để biến nó thành UnicodeScalars, sau đó bạn có thể chuyển đổi thành một String.

Đó là một chút của một mục grungy, phải mất một máy phát điện (vì nó xử lý stateful) và trả về một enum chỉ ra một kết quả (với một loại liên quan của vô hướng), hoặc một lỗi hoặc hoàn thành. Kết hợp mẫu Swift 2.0 giúp dễ sử dụng hơn nhiều:

let u16data: [UInt16] = [0xD83D,0xDC36] 
//or let u16data = "Hello, ".utf16 

var g = u16data.generate() 
var s: String = "" 
var utf16 = UTF16() 
while case let .Result(scalar) = utf16.decode(&g) { 
    print(scalar, &s) 
} 
print(s) // prints 
+0

Tôi mất một chút thời gian để tìm hiểu một số khái niệm mới (1. [phương thức giải mã] (https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_UTF16_Structure/index.html), 2. máy phát điện ([ở đây] (https: // vi. wikipedia.org/wiki/Generator_(computer_programming)) và [tại đây] (http://devsmash.com/blog/whats-the-big-deal-with-generators)), 3. [stateful] (http: // programmers.stackexchange.com/a/154499/186547)), nhưng đây là một câu trả lời hữu ích. Tôi đoán câu trả lời cho câu hỏi ban đầu của tôi là không, không có gì được xây dựng trong Swift để làm điều này trực tiếp, nhưng nó không phải là quá khó để tạo ra. – Suragch

4

Có các công thức để tính điểm mã ban đầu dựa trên cặp thay thế và ngược lại. Từ https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae:

Section 3.7 of The Unicode Standard 3.0 xác định thuật toán để chuyển đổi sang và từ các cặp thay thế.

Một điểm mã C lớn hơn 0xFFFF tương ứng với một cặp thay thế <H, L> theo công thức sau:

H = Math.floor((C - 0x10000)/0x400) + 0xD800 
L = (C - 0x10000) % 0x400 + 0xDC00 

Ánh xạ ngược lại, tức là từ một cặp thay thế <H, L> đến một Unicode điểm mã C, là được cung cấp bởi:

C = (H - 0xD800) * 0x400 + L - 0xDC00 + 0x10000 
Các vấn đề liên quan