当表情符号出现时,使用NSRegularExpression会产生错误的范围 [英] Using NSRegularExpression produces incorrect ranges when emoji are present

查看:0
本文介绍了当表情符号出现时,使用NSRegularExpression会产生错误的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从用户提供的字符串中解析出"@mentions"。正则表达式本身似乎可以找到它们,但当表情符号出现时,它提供的范围是不正确的。

let text = "😂😘🙂 @joe "
let tagExpr = try? NSRegularExpression(pattern: "@\S+")
tagExpr?.enumerateMatches(in: text, range: NSRange(location: 0, length: text.characters.count)) { tag, flags, pointer in
    guard let tag = tag?.range else { return }

    if let newRange = Range(tag, in: text) {
        let replaced = text.replacingCharacters(in: newRange, with: "[email]")
        print(replaced)
    }
}

运行此命令时 tag=(位置:7,长度:2)

并打印出来 😂😘🙂 [email]oe

预期结果为 😂😘🙂 [email]

推荐答案

NSRegularExpression(以及涉及NSRange的任何内容)对UTF16计数/索引进行操作。就这一点而言,NSString.count也被计入UTF16。

但在您的代码中,您告诉NSRegularExpression使用长度text.characters.count。这是组成的字符数,而不是UTF16计数。您的字符串"😂😘🙂 @joe "有9个组成字符,但有12个UTF16代码单元。因此,您实际上是在告诉NSRegularExpression只查看前9个UTF16代码单元,这意味着它忽略了尾随的"oe "

修复程序将通过length: text.utf16.count

let text = "😂😘🙂 @joe "
let tagExpr = try? NSRegularExpression(pattern: "@\S+")
tagExpr?.enumerateMatches(in: text, range: NSRange(location: 0, length: text.utf16.count)) { tag, flags, pointer in
    guard let tag = tag?.range else { return }

    if let newRange = Range(tag, in: text) {
        let replaced = text.replacingCharacters(in: newRange, with: "[email]")
        print(replaced)
    }
}

这篇关于当表情符号出现时,使用NSRegularExpression会产生错误的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆