我将展示代码和输出,因为它更容易解释问题。
注释行中的代码和输出:
let greekLetter = "β"
let string1 = greekLetter
/// string2 is the same as string1 but converted to NSString then back to String
let string2 = String(NSString(string: greekLetter))
print(string1.range(of: greekLetter)!)
/// prints: Index(_rawBits: 0)..<Index(_rawBits: 131072)
print(string2.range(of: greekLetter)!)
/// prints: Index(_rawBits: 0)..<Index(_rawBits: 65536)
问题:包含希腊字母的 String 返回的范围与具有相同希腊字母的相同 String 转换为 NSString 然后再次返回 String 的范围不同。
有什么想法吗?
为什么提出这个问题: 我正在做一些解析,我需要找到特定字符串的范围,然后插入其他内容来代替它。由于错误的范围返回错误的位置插入字符串由于错误的下限/上限位置。
更新 2:
假设我有一个任务:在给定的字符串“β-1”中将“1”更改为“2”。这个字符串来自服务器。 请查看此代码示例:
let wordWithGreekLetter = "β-1"
var string1 = wordWithGreekLetter
let data = """
{ "name" : "\(wordWithGreekLetter)" }
""".data(using: String.Encoding.utf8)
struct User: Decodable {
let name: String
}
let user = try! JSONDecoder().decode(User.self, from: data!)
/// string2 is the same as string1 but decoded from the data
var string2 = user.name
let rangeOfNumberOne1 = string1.range(of: "1")!
string1.removeSubrange(rangeOfNumberOne1)
string1.insert("2", at: rangeOfNumberOne1.lowerBound)
/// RESULT: string1 = "β-2"
let rangeOfNumberOne2 = string2.range(of: "1")!
string2.removeSubrange(rangeOfNumberOne2)
string2.insert("2", at: rangeOfNumberOne2.lowerBound)
/// RESULT: string2 = "β2-"
最佳答案
正如 Rob 在 Why is startIndex not equal to endIndex shifted to startIndex position in String in Swift? 中解释的那样,索引的原始位是一个实现细节,您不应该关心该值。
实际问题是(引自 Collection ):
Saved indices may become invalid as a result of mutating operations.
因此在您对字符串调用 removeSubrange()
后,rangeOfNumberOne1/2
可能不再有效。
在这种特殊情况下,可能发生在 string2
(从 NSString
桥接而来)因为删除一个字符可能 重组内部存储。但这纯粹是推测:唯一重要的是当前代码表现出未定义的行为。
如果你更换
let rangeOfNumberOne1 = string1.range(of: "1")!
string1.removeSubrange(rangeOfNumberOne1)
string1.insert("2", at: rangeOfNumberOne1.lowerBound)
通过
let rangeOfNumberOne1 = string1.range(of: "1")!
string1.replaceSubrange(rangeOfNumberOne1, with: "2")
(对于 string2
也是类似的)那么你会得到两个字符串相同的结果“β-2”。
关于swift - 希腊字母的字符串范围不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57657588/