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

如何将字符串中的指定UTF8 NSRange转换为UTF16 NSRange

将字符串中的指定UTF8 NSRange转换为UTF16 NSRange

我只能获取到UTF8格式的NSRange范围,需要实现将任意给定的UTF8 NSRange转换为UTF16 NSRange的功能。

示例:

let str = #"let 🎁🇵🇷 = "hello world""#

// 🎁🇵🇷的UTF8 NSRange为:{4, 12}
// 🎁🇵🇷的UTF16 NSRange为:{4, 6}

// let 🎁🇵🇷的UTF8 NSRange为:{0, 16}
// let 🎁🇵🇷的UTF16 NSRange为:{0, 10}

计数测试:

print("🎁🇵🇷".utf8.count) // 12
print("🎁🇵🇷".utf16.count) // 6

print("let 🎁🇵🇷".utf8.count) // 16
print("let 🎁🇵🇷".utf16.count) // 10

解决方案

可以通过String的不同编码视图转换索引来实现,以下是Swift的实现代码:

import Foundation

extension String {
    func utf16Range(from utf8Range: NSRange) -> NSRange? {
        guard let utf8Start = utf8.index(utf8.startIndex, offsetBy: utf8Range.location, limitedBy: utf8.endIndex),
              let utf8End = utf8.index(utf8Start, offsetBy: utf8Range.length, limitedBy: utf8.endIndex),
              let start = String.Index(utf8Start, within: self),
              let end = String.Index(utf8End, within: self) else {
            return nil
        }
        let utf16Start = start.utf16Offset(in: self)
        let utf16End = end.utf16Offset(in: self)
        return NSRange(location: utf16Start, length: utf16End - utf16Start)
    }
}

// 测试使用
let str = #"let 🎁🇵🇷 = "hello world""#
if let utf16Range1 = str.utf16Range(from: NSRange(location: 4, length: 12)) {
    print(utf16Range1) // 输出: {4, 6}
}
if let utf16Range2 = str.utf16Range(from: NSRange(location: 0, length: 16)) {
    print(utf16Range2) // 输出: {0, 10}
}

代码说明:

  • 先通过utf8.index将UTF8 NSRange的起始位置和长度转换为UTF8视图的索引
  • 再通过String.Index(_:within:)将UTF8索引转换为字符串的通用索引
  • 最后用utf16Offset(in:)获取该索引在UTF16视图中的位置,计算得到目标UTF16 NSRange
  • 加入安全判断,若输入的UTF8 NSRange越界则返回nil

内容的提问来源于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.30 20:57:27