如何根据原始字符串获取嵌套子串的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 }
优化点说明
- 简化参数传递:将查找子串在原始字符串中Range的逻辑整合到extension方法内,无需外部手动传入子串的Range,调用更直观。
- 安全的可选值处理:新增空值判断,避免强制解包带来的崩溃风险。
- 更简洁的偏移计算:直接使用
String原生的distance(from:to:)方法计算偏移,无需依赖utf8视图,代码更简洁且符合Swift字符串的设计逻辑。
内容的提问来源于stack exchange,提问作者Hassan Taleb
相关产品推荐
相关产品推荐

