如何获取字符串中子串范围并应用到另一字符串,Swift实现异常求解
问题原因
核心差异来自Objective-C与Swift中字符串范围的设计区别:
- Objective-C的
NSString采用UTF-16编码,NSRange存储的是UTF-16编码单元的偏移量,单个阿拉伯数字、单个中文在UTF-16中都只占1个编码单元,因此从数字字符串拿到的NSRange可以直接套用在结构一致的中文字符串上,能得到正确结果。 - Swift的
String.Range是和所属字符串实例绑定的专属索引,不能直接跨字符串使用,即使两个字符串长度一致,直接复用范围会产生未定义行为。你现有Swift代码中直接将从数字字符串拿到的Range作为下标去访问中文字符串,属于非法操作,这就是得到错误返回值的根本原因。
正确实现
你需要先将输入字符在数字字符串中的位置转换为整数偏移量,再用该偏移量从对应的中文字符串中取值,参考代码如下:
func foobar(input: String) -> String { let digitString = "0123456789" let chineseDigitString = "零一二三四五六七八九" // 匹配输入字符在数字串中的范围,不匹配时返回空兜底 guard let range = digitString.range(of: input) else { return "" } // 将范围起始位置转换为整数偏移量 let offset = digitString.distance(from: digitString.startIndex, to: range.lowerBound) // 计算中文字符串对应位置的合法索引 let targetIndex = chineseDigitString.index(chineseDigitString.startIndex, offsetBy: offset) // 取值返回 return String(chineseDigitString[targetIndex]) }
调用示例:输入"1"时会返回预期的"一"。
内容的提问来源于stack exchange,提问作者NSFish
相关产品推荐
相关产品推荐

