
[英]Changing the title of a UIButton attributedStrings enumerateSubstrings strings ranges
[英]Inconsistent ranges of strings with greek letter
我将显示代码和输出,因为它更容易解释问题。
注释行中的代码和输出:
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)
问题:包含希腊字母的字符串返回的范围不同于已转换为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所解释的, 为什么在Swift中String中的startIndex不等于endIndex移到字符串中的startIndex位置? ,索引的原始位是实现细节,因此您不必关心该值。
实际的问题是(来自Collection的引用):
由于进行突变操作,保存的索引可能会变得无效。
因此,在对字符串调用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”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.