繁体   English   中英

带有希腊字母的字符串范围不一致

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM