2015-07-08 12 views
13

Tôi muốn viết một chuỗi Unicode sử dụng các giá trị thập lục phân trong Swift. Tôi đã đọc documentation cho String và nhân vật vì vậy tôi biết rằng tôi có thể sử dụng các ký tự Unicode đặc biệt trực tiếp trong chuỗi như sau:Cách thể hiện các chuỗi trong Swift bằng cách sử dụng các giá trị thập lục phân Unicode (UTF-16)

var variableString = "Cat‼" // "Cat" + Double Exclamation + cat emoji 

Nhưng tôi muốn làm điều đó bằng cách sử dụng các điểm mã Unicode. Các tài liệu (và this question) hiển thị nó cho các ký tự, nhưng không rõ ràng về cách thực hiện nó cho các chuỗi.

(Lưu ý: Mặc dù câu trả lời có vẻ hiển nhiên đối với tôi bây giờ, nó không hiển nhiên chút nào trong một thời gian ngắn trước đây. Tôi trả lời câu hỏi của tôi dưới đây như một phương tiện học cách làm điều này và cũng để giúp bản thân mình hiểu Unicode ngữ và cách nhân vật và Strings việc Swift.)

Trả lời

24

Cập nhật cho Swift 3

Character

cú pháp Swift cho tạo thành một hệ thập lục phân code point

\u{n} 

trong đó n là số thập lục phân dài tối đa 8 chữ số. Phạm vi hợp lệ cho Unicode scalar là từ U + 0 đến U + D7FF và U + E000 đến U + 10FFFF. (U + D800 tới phạm vi U + DFFF là dành cho surrogate pairs, mà không vô hướng bản thân, nhưng được sử dụng trong UTF-16 để mã hóa các vô hướng giá trị cao hơn.)

Ví dụ:

// The following forms are equivalent. They all produce "C". 
let char1: Character = "\u{43}" 
let char2: Character = "\u{0043}" 
let char3: Character = "\u{00000043}" 

// Higher value Unicode scalars are done similarly 
let char4: Character = "\u{203C}" // ‼ (DOUBLE EXCLAMATION MARK character) 
let char5: Character = "\u{1F431}" // (cat emoji) 

// Characters can be made up of multiple scalars 
let char7: Character = "\u{65}\u{301}" // é = "e" + accent mark 
let char8: Character = "\u{65}\u{301}\u{20DD}" // é⃝ = "e" + accent mark + circle 

Ghi chú :

  • số không hàng đầu có thể được thêm vào hoặc bỏ qua
  • Nhân vật được gọi là extended grapheme clusters. Ngay cả khi chúng được tạo thành từ nhiều vô hướng, chúng vẫn được coi là một ký tự đơn. Điều quan trọng là chúng dường như là một ký tự đơn (grapheme) cho người dùng.
  • TODO: How to convert surrogate pair to Unicode scalar in Swift

Chuỗi

Strings bao gồm các ký tự. Xem các ví dụ sau cho một số cách để tạo chúng bằng cách sử dụng các điểm mã thập lục phân.

Ví dụ:

var string1 = "\u{0043}\u{0061}\u{0074}\u{203C}\u{1F431}" // Cat‼ 

// pass an array of characters to a String initializer 
let catCharacters: [Character] = ["\u{0043}", "\u{0061}", "\u{0074}", "\u{203C}", "\u{1F431}"] // ["C", "a", "t", "‼", ""] 
let string2 = String(catCharacters) // Cat‼ 

Chuyển đổi giá trị Hex tại Runtime

Khi chạy bạn có thể chuyển đổi hệ thập lục phân hoặc Int giá trị vào một Character hoặc String bằng cách đầu tiên chuyển đổi nó vào một UnicodeScalar.

Ví dụ:

// hex values 
let value0: UInt8 = 0x43  // 97 
let value1: UInt16 = 0x203C // 22823 
let value2: UInt32 = 0x1F431 // 127822 

// convert hex to UnicodeScalar 
let scalar0 = UnicodeScalar(value0) 
// make sure that UInt16 and UInt32 form valid Unicode values 
guard 
    let scalar1 = UnicodeScalar(value1), 
    let scalar2 = UnicodeScalar(value2) else { 
    return 
} 

// convert to Character 
let character0 = Character(scalar0) // C 
let character1 = Character(scalar1) // ‼ 
let character2 = Character(scalar2) // 

// convert to String 
let string0 = String(scalar0) // C 
let string1 = String(scalar1) // ‼ 
let string2 = String(scalar2) // 

// convert hex array to String 
let myHexArray = [0x43, 0x61, 0x74, 0x203C, 0x1F431] // an Int array 
var myString = "" 
for hexValue in myHexArray { 
    if let scalar = UnicodeScalar(hexValue) { 
     myString.append(Character(scalar)) 
    } 
} 
print(myString) // Cat‼ 

Đọc thêm

+0

@Suragch Tôi có một ký tự unicode '\ u {0D85}'. Làm thế nào để tôi nhận được giá trị Int từ nó? – Isuru

+0

@Isuru, tôi đã hỏi lại và trả lời câu hỏi của bạn ở đây: [Cách chuyển đổi Ký tự Unicode thành Int trong Swift] (http://stackoverflow.com/questions/38779114/how-to-convert-unicode-character-to -int-in-swift) – Suragch

+0

@Suragch Cảm ơn rất nhiều vì câu trả lời chi tiết. Tôi thực sự tìm thấy cách để làm điều đó trong [câu trả lời] này (http://stackoverflow.com/a/24102584/1077789). Nhưng vẫn còn, tốt để có một lời giải thích kỹ lưỡng. – Isuru

1

từ Hex của bạn "0x1F52D" để thực Emoji

let c = 0x1F602 

bước tiếp theo có thể sẽ nhận được một uint32 từ Hex của bạn

let intEmoji = UnicodeScalar(c!).value 

từ này, bạn có thể làm điều gì đó như

titleLabel.text = String(UnicodeScalar(intEmoji)!) 

tại đây bạn có một ""

cho nó hoạt động với phạm vi của hệ thập lục phân quá

let emojiRanges = [ 
      0x1F600...0x1F636, 
      0x1F645...0x1F64F, 
      0x1F910...0x1F91F, 
      0x1F30D...0x1F52D 
     ] 

     for range in emojiRanges { 
      for i in range { 
       let c = UnicodeScalar(i)!.value 
       data.append(c) 
      } 
     } 

để có được nhiều UInt32 từ cự ly Hex của bạn cho exemple

+0

Vui lòng không đăng cùng một câu trả lời cho nhiều câu hỏi. Nếu cùng một thông tin thực sự trả lời cả hai câu hỏi, thì một câu hỏi (thường là câu hỏi mới hơn) nên được đóng thành bản sao của câu hỏi kia. Bạn có thể chỉ ra điều này bằng cách [bỏ phiếu để đóng nó như là một bản sao] (http://stackoverflow.com/help/privileges/close-questions) hoặc, nếu bạn không có đủ danh tiếng cho điều đó, [giơ cờ] (http://stackoverflow.com/help/privileges/flag-posts) để cho biết rằng đó là bản sao. Nếu không, hãy đảm bảo bạn điều chỉnh câu trả lời cho câu hỏi * này * và không chỉ dán cùng một câu trả lời ở nhiều nơi. –

Các vấn đề liên quan