【发布时间】:2021-09-11 08:11:57
【问题描述】:
Unicode 字符串中带有重音符号的字符可以用“短”(组合)和“长”(分解)格式表示。这意味着在 Xcode 中,字符串 a 的长度为 8,而字符串 b 的长度为 10,即使它们看起来相同:
let a:String = "δέκα" // 8 bytes
print(a.data(using:String.Encoding.utf8)!.count)
let b:String = "δέκα" // 10 bytes
print(b.data(using:String.Encoding.utf8)!.count)
我需要“缩小”字符串以确保它们始终采用较短的“组合”格式。这是如何在 Swift 中完成的?
脚注:我知道像这样(如下)完全去除重音是可能的。我不想那样做,我只想“组合”角色。
let usPosixLocale = Locale(identifier: "en_US_POSIX")
let out = "δέκα".folding(options: [.caseInsensitive, .diacriticInsensitive], locale: usPosixLocale)
我知道.widthInsensitive 选项,但文档似乎表明它仅适用于亚洲字符。所以具体来说,这 不 用于组合或分解字符:
let out = a.folding(options: [.widthInsensitive], locale: usPosixLocale)
更新
这是代码的第二个较长版本,为了清楚起见显示了字节差异。
let a:String = String(bytes:[206, 180, 206, 173, 206, 186, 206, 177], encoding:.utf8)!
print(a, a.data(using:String.Encoding.utf8)!.count)
let b:String = String(bytes:[206, 180, 206, 181, 204, 129, 206, 186, 206, 177], encoding:.utf8)!
print(b, b.data(using:String.Encoding.utf8)!.count)
let usPosixLocale = Locale(identifier: "en_US_POSIX")
let out = b.folding(options: [.widthInsensitive], locale: usPosixLocale)
print(out.data(using:String.Encoding.utf8)!.count)
【问题讨论】:
-
当我从这里复制/粘贴到 iPad Playground (Swift 5.3) 时,我得到了
8,请参阅 imgur.com/VsXdFpc -
您能否使用
for unit in a.utf8 { print(unit) }共享a和b的UTF8 单位输出 -
也许是 Stackoverflow 或浏览器复制粘贴规范了它。我会想办法把字节放进去。
-
好的,我已经添加了相同代码的第二个更长(但更难阅读)的副本,其中字符串表示为字节,因此代码绝对是可重现的)
-
我认为你想要的词是“规范化”。 developer.apple.com/documentation/corefoundation/…
标签: swift string unicode unicode-normalization