这应该很简单......
import Foundation
let str:String = "Beyonce\u{301} and Tay"
print(str)
print(str.components(separatedBy: CharacterSet(charactersIn: "e")))
编译正常,直到我运行可执行文件:
// Beyoncé and Tay
// Illegal instruction (core dumped)
我怀疑 Swift 很难处理组合的 '\u{65}'
重音标记,但考虑到该语言对其基于字素的字符串模型的强调程度,我认为它会是很明显,在 'e'
上拆分 "Beyonce\u{301} and Tay"
应该只给出 ["B", "yonce\u{301}和 Tay"]
,bởi vì 'e\u{301}'
应该被解释为单个字素,而不是 'e'
加上组合锐音符。
拆分单个字符不会崩溃:
print(str.components(separatedBy: "e"))
// ["B", "yoncé and Tay"]
我的swift版本是
swiftc -version
Swift version 3.0-dev (LLVM 3e3d712024, Clang 09ad59b006, Swift fdf6ee20e4)
Target: x86_64-unknown-linux-gnu
看起来 Swift 的 Linux 端口中存在错误。我不会在我的回答中解决这个问题。以下代码已在 Mac OS X 上进行测试。
您遇到了 Unicode 规范化问题。字母 é
可以用两种方式表示,Swift 认为它们是相同的:
let s1 = "e\u{301}" // letter e + combining acute accent
let s2 = "\u{0e9}" // small letter e with acute
s1.characters.count // 1
s2.characters.count // 1
s1 == s2 // true
那是因为 Swift 的 Sợi dây
和它的前身 NSString
一样对 Unicode 有很好的支持。但如果深入研究,您会开始发现一些差异:
s1.utf16.count // 2
s2.utf16.count // 1
因此,即使 s1
Và s2
相等,它们的存储方式也不同:使用 2 个或 1 个代码点。 components(seperatedBy: )
对这个事实视而不见。它遍历字符串中的所有代码点,如果找到字母 e
则拆分。将一种形式转换为另一种形式称为规范化,它会影响函数的工作方式:
let str1 = "Beyonce\u{301} and Tay"
let str2 = str1.precomposedStringWithCanonicalMapping // normalize the string to Form C
let charset = CharacterSet(charactersIn: "e")
str1.components(separatedBy: charset) // ["B", "yonc", "́ and Tay"]
str2.components(separatedBy: charset) // ["B", "yoncé and Tay"]
引用资料:
Tôi là một lập trình viên xuất sắc, rất giỏi!