swift - 希腊字母的字符串范围不一致

标签 swift string range nsstring

我将展示代码和输出,因为它更容易解释问题。

注释行中的代码和输出:

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/

相关文章:

ios - swift - 在 UITableVIew 中将多选设置为 true 时如何设置选择颜色

ios - 如何在 iOS Swift 中显示来自新 Firebase 的个人资料图片?

Java:将整数数组复制到字符串数组中

mysql - 基于一系列值返回结果,即 WHERE ColA = (ColB + n OR ColB - n)

ios - 如何使 UIImageView 在视觉上可点击和可选择

ios - Xcode Storyboard用蓝色遮盖了 uitabbarcontroller 元素

javascript - 在 JavaScript 正则表达式中链接多个正向前瞻

PHP substr 和 strlen 的替代方案

vba - 如何使用 RefersToRange?

java - 在独占范围内生成随机 double