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

Swift中NSRange.location与NSRange.length的替代方案及字符串提取实现

Swift中NSRange的替代方案及OC代码转Swift实现

你可以通过两种方式实现类似Objective-C的range逻辑来提取SIP地址中的名称:一种是使用Swift原生的Range<String.Index>,另一种是通过桥接NSString复用熟悉的NSRange方法。

方式一:纯Swift原生API实现

这种方式完全使用Swift字符串的索引区间,无需手动计算位置和长度:

extension String {
    func extractSIPName() -> String? {
        // 先查找"sip:",找不到再试"sips:"
        var sipRange: Range<String.Index>? = self.range(of: "sip:")
        if sipRange == nil {
            sipRange = self.range(of: "sips:")
        }
        
        // 查找@的位置,找不到直接返回nil
        guard let atRange = self.range(of: "@") else {
            return nil
        }
        
        if let validSipRange = sipRange {
            // 从sip前缀的结束位置到@的起始位置截取子串
            let start = validSipRange.upperBound
            let end = atRange.lowerBound
            return String(self[start..<end])
        } else {
            // 没有找到sip前缀,直接取开头到@的部分
            return String(self[..<atRange.lowerBound])
        }
    }
}

// 使用示例
let sipString = "sip:name@xyz.com"
if let userName = sipString.extractSIPName() {
    print(userName) // 输出:name
}

方式二:桥接NSString复用NSRange逻辑

如果你想完全照搬原Objective-C的代码结构,可以将Swift字符串桥接为NSString,直接使用NSRange相关方法:

extension String {
    func extractSIPNameWithNSRange() -> String? {
        let nsSelf = self as NSString
        var sipRange = nsSelf.range(of: "sip:")
        
        // 找不到sip:则查找sips:
        if sipRange.location == NSNotFound {
            sipRange = nsSelf.range(of: "sips:")
        }
        
        let atRange = nsSelf.range(of: "@")
        
        // 同时找到sip前缀和@,截取中间部分
        if sipRange.location != NSNotFound && atRange.location != NSNotFound {
            let startPos = sipRange.location + sipRange.length
            let subLength = atRange.location - startPos
            return nsSelf.substring(with: NSMakeRange(startPos, subLength))
        } else if atRange.location != NSNotFound {
            // 只有@,截取开头到@的部分
            return nsSelf.substring(with: NSMakeRange(0, atRange.location))
        }
        
        return nil
    }
}

// 使用示例
let testString = "sips:john@example.com"
if let userName = testString.extractSIPNameWithNSRange() {
    print(userName) // 输出:john
}

补充:简洁的components方式

你提到的components(separatedBy:)也能快速实现需求,适合简单场景:

let sipString = "sip:name@xyz.com"
let components = sipString.components(separatedBy: ["sip:", "sips:", "@"])
// 取第一个非空的部分
if let userName = components.first(where: { !$0.isEmpty }) {
    print(userName) // 输出:name
}

内容的提问来源于stack exchange,提问作者Sagar D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:52:45