This question already has an answer here:
Swift Regex doesn't work
(1个答案)
2年前关闭。
我正在尝试从用户提供的字符串中解析出“@mentions”。正则表达式本身似乎可以找到它们,但是当存在表情符号时,它提供的范围不正确。
运行时
并打印出来
预期结果是
(1个答案)
2年前关闭。
我正在尝试从用户提供的字符串中解析出“@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)
}
}
关于ios - 存在表情符号时,使用NSRegularExpression会产生不正确的范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46495365/
10-12 01:49