如何在Character不先将其转换为String?的情况下提取给定的Unicode代码点?我知道我可以使用以下内容:
let ch: Character = "A"
let s = String(ch).unicodeScalars
s[s.startIndex].value // returns 65
Run Code Online (Sandbox Code Playgroud)
但似乎应该有一个更直接的方法来完成这个使用Swift的标准库.语言指南"使用字符"和"Unicode"部分仅讨论迭代a中的字符String,而不是直接使用Characters.
Eri*_*rik 32
根据我在文档中收集的内容,他们希望您Character从a 获取值,String因为它提供了上下文.这是Character用UTF8,UTF16还是21位代码点(标量)编码的?
如果你看看如何Character在Swift框架中定义a ,它实际上是一个enum值.这可能是由于做从各种表示String.utf8,String.utf16和String.unicodeScalars.
看起来他们不希望你使用Character值,而是Strings你和程序员决定如何从String自身获取这些,允许编码被保留.
也就是说,如果你需要以简洁的方式获得代码点,我会建议像这样的扩展:
extension Character
{
func unicodeScalarCodePoint() -> UInt32
{
let characterString = String(self)
let scalars = characterString.unicodeScalars
return scalars[scalars.startIndex].value
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
let char : Character = "A"
char.unicodeScalarCodePoint()
Run Code Online (Sandbox Code Playgroud)
总之,当您考虑所有可能性时,字符串和字符编码是一件棘手的事情.为了能够表达每种可能性,他们采用了这种方案.
还要记住这是一个1.0版本,我相信他们很快就会扩展Swift的语法糖.
SLN*_*SLN 18
我认为对Unicode有一些误解.Unicode本身不是一种编码,它不会将任何字形集群(或人类阅读方面的"字符")转换为任何类型的二进制序列.Unicode只是一个大表,它收集地球上所有语言使用的所有字形簇(非正式地还包括克林贡语).这些字形簇由代码点组织和索引(swift中的21位数字,看起来像U + D800).您可以使用代码点在大型Unicode表中找到您要查找的字符的位置
同时,称为UTF8,UTF16,UTF32的协议实际上是编码.是的,有多种方法可以将Unicode字符编码为二进制序列.使用哪种协议取决于您正在使用的项目,但大多数网页都是由UTF-8编码的(您现在可以实际检查它).
概念1: Unicode点在Swift中称为Unicode标量
Unicode标量是U + 0000到U + D7FF(含)或U + E000到U + 10FFFF(含)的任何Unicode代码点.Unicode标量不包括Unicode代理对代码点,它们是U + D800到U + DFFF范围内的代码点.
概念2:该代码单元是编码的抽象表示.
请考虑以下代码段
let theCat = "Cat!"
for char in theCat.utf8 {
print("\(char) ", terminator: "") //Code Unit of each grapheme cluster for the UFT8 encoding
}
print("")
for char in theCat.utf8 {
print("\(String(char, radix: 2)) ", terminator: "") //Encoding of each grapheme cluster for the UTF8 encoding
}
print("")
for char in theCat.utf16 {
print("\(char) ", terminator: "") //Code Unit of each grapheme cluster for the UFT-16 encoding
}
print("")
for char in theCat.utf16 {
print("\(String(char, radix: 2)) ", terminator: "") //Encoding of each grapheme cluster for the UTF-16 encoding
}
print("")
for char in theCat.unicodeScalars {
print("\(char.value) ", terminator: "") //Code Unit of each grapheme cluster for the UFT-32 encoding
}
print("")
for char in theCat.unicodeScalars {
print("\(String(char.value, radix: 2)) ", terminator: "") //Encoding of each grapheme cluster for the UTF-32 encoding
}
Run Code Online (Sandbox Code Playgroud)
抽象表示意味着:代码单元由基数为10的数字(十进制数)写入,它等于基数为2的编码(二进制序列).对机器进行编码,代码单元更适合人类,它比二进制序列更容易阅读.
概念3:字符可能具有不同的Unicode点.这取决于角色如何通过什么字形聚类来收缩(这就是为什么我在开始时从人类阅读方面说"人物")
请考虑以下代码段
let precomposed: String = "\u{D55C}"
let decomposed: String = "\u{1112}\u{1161}\u{11AB}"
print(precomposed.characters.count) // print "1"
print(decomposed.characters.count) // print "1" => Character != grapheme cluster
print(precomposed) //print "?"
print(decomposed) //print "?"
Run Code Online (Sandbox Code Playgroud)
的字符precomposed和decomposed在视觉上和语言相等,但是他们有不同的Unicode点和不同的代码单元,如果他们通过相同的编码协议编码的(见下面例子)
for preCha in precomposed.utf16 {
print("\(preCha) ", terminator: "") //print 55357 56374 128054 54620
}
print("")
for deCha in decomposed.utf16 {
print("\(deCha) ", terminator: "") //print 4370 4449 4523
}
Run Code Online (Sandbox Code Playgroud)
额外的例子
var word = "cafe"
print("the number of characters in \(word) is \(word.characters.count)")
word += "\u{301}"
print("the number of characters in \(word) is \(word.characters.count)")
Run Code Online (Sandbox Code Playgroud)
总结:Code Points,Aka是Unicode中字符的位置索引,与UTF-8,UTF-16和UTF-32编码方案无关.
进一步阅读:
http://www.joelonsoftware.com/articles/Unicode.html
http://kunststube.net/encoding/
https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html
我认为问题在于它Character不代表Unicode代码点.它代表一个"Unicode字形集群",它可以包含多个代码点.
相反,UnicodeScalar表示Unicode代码点.
我同意你的看法,应该有一种直接从角色获取代码的方法.但我能提供的只是一个简写:
let ch: Character = "A"
for code in String(ch).utf8 { println(code) }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
37644 次 |
| 最近记录: |