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

如何根据原始字符串获取嵌套子串的Range?求更简洁实现方案

简化子串Range到原始字符串Range的转换

已知原始字符串为"hello 111abc222 world",子串"111abc222"中"abc"的Range已获取,需要将该Range映射到原始字符串的对应位置。以下是更简洁的实现方案:

优化后的代码实现

extension String {
    /// 将当前字符串中指定的子Range转换为其在原始字符串中的对应Range
    /// - Parameters:
    ///   - originalString: 包含当前字符串的原始父字符串
    ///   - subRange: 当前字符串内的目标Range
    /// - Returns: 原始字符串中对应的Range,若当前字符串不在原始字符串中则返回nil
    func mappedRange(in originalString: String, for subRange: Range<String.Index>) -> Range<String.Index>? {
        guard let selfInOriginalRange = originalString.range(of: self) else {
            return nil
        }
        // 计算目标Range在当前字符串中的起始、结束偏移量
        let startOffset = distance(from: startIndex, to: subRange.lowerBound)
        let endOffset = distance(from: startIndex, to: subRange.upperBound)
        // 基于当前字符串在原始字符串中的位置,偏移得到目标Range
        let originalStart = originalString.index(selfInOriginalRange.lowerBound, offsetBy: startOffset)
        let originalEnd = originalString.index(selfInOriginalRange.lowerBound, offsetBy: endOffset)
        return originalStart..<originalEnd
    }
}

// 使用示例
let subStr = "111abc222"
let originalStr = "hello \(subStr) world"

if let abcInSubStrRange = subStr.range(of: "abc"),
   let abcInOriginalRange = subStr.mappedRange(in: originalStr, for: abcInSubStrRange) {
    print(originalStr[abcInOriginalRange]) // 输出: abc
}

优化点说明

  1. 简化参数传递:将查找子串在原始字符串中Range的逻辑整合到extension方法内,无需外部手动传入子串的Range,调用更直观。
  2. 安全的可选值处理:新增空值判断,避免强制解包带来的崩溃风险。
  3. 更简洁的偏移计算:直接使用String原生的distance(from:to:)方法计算偏移,无需依赖utf8视图,代码更简洁且符合Swift字符串的设计逻辑。

内容的提问来源于stack exchange,提问作者Hassan Taleb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:15:20