You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中指定.backwards选项为何未从字符串末尾反向匹配?

问题解答

1. 关于Index(_rawBits: ...)的含义

Swift的String.Index是用于标记字符串字符位置的结构体,由于Swift字符串基于Unicode标量存储(并非简单的字节偏移),_rawBits是它内部用于存储位置信息的私有属性,属于底层实现细节,对外没有实际参考价值,只是打印时会显示这个内部值。

如果需要获取可读的位置偏移量,可以用distance(from:to:)方法计算从字符串起始索引到匹配位置的距离:

let offset = greeting.distance(from: greeting.startIndex, to: match.lowerBound)
print("匹配位置的偏移量:\(offset)")

2. .backwards选项未生效的原因

问题出在你同时使用了.backwards和.regularExpression选项,两者组合后的行为和预期不符:

  • 当不使用正则表达式时,.backwards会让range(of:)从字符串末尾向前查找,返回第一个匹配到的结果(也就是最后一个出现的"o")。
  • 当使用正则表达式时,.backwards的作用被改变:它仅让正则引擎从搜索范围的末尾向开头扫描,但正则匹配逻辑仍然锚定在搜索范围的起始位置(整个字符串的开头)。对于"o"这种无锚定的简单模式,引擎还是会找到最左边的匹配项,所以无论加不加.backwards,结果都是第一个"o"。

解决方法

方法一:去掉正则表达式选项(推荐)

如果只是查找最后一个"o",完全不需要正则,直接使用.backwards即可:

import UIKit

var greeting = "Hello, playground"

if let match = greeting.range(of: "o", options: .backwards) {
    let lower = greeting.prefix(upTo: match.lowerBound) // 替代已废弃的substring(to:)
    let upper = greeting.suffix(from: match.lowerBound) // 替代已废弃的substring(from:)
    print("lower '\(lower)' upper '\(upper)'")
}

这段代码会输出:lower 'Hello, playgr' upper 'ound',符合你的预期。

方法二:修改正则模式(必须用正则时)

如果必须使用正则查找最后一个"o",可以修改正则模式为匹配最后一个出现的目标字符:

if let match = greeting.range(of: "o(?=[^o]*$)", options: .regularExpression) {
    let lower = greeting.prefix(upTo: match.lowerBound)
    let upper = greeting.suffix(from: match.lowerBound)
    print("lower '\(lower)' upper '\(upper)'")
}

这里的模式o(?=[^o]*$)利用正向预查,匹配后面没有其他"o"的目标字符,也就是最后一个"o"。

内容的提问来源于stack exchange,提问作者Grzegorz Adam Hankiewicz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:00:15