swift - 正则表达式 unicode 在 swift 中不起作用

标签 swift regex unicode emoji nsregularexpression

let regex1 = "(\\ud83d\\udc68)"
let regex2 = "(\\ud83d[\\udc68-\\udc69])"

"👨".capturedGroupsFull(forRegex: regex1)
// returns 1 match: [(.0 "👨", .1 {0, 2})]
"👨".capturedGroupsFull(forRegex: regex2)
// returns nil

为什么第一行返回一个匹配项而第二行​​没有匹配项?

  • 两个正则表达式在 regex101 上都可以正常工作。 (例如设置为 javascript 并使用第二个正则表达式作为 (\ud83d[\udc68-\udc69]))。
  • 我是 使用 Swift 4.0。
  • 此正则表达式 "(\\ud83d[\\udc68])" 还将 在 Playground 中测试时返回 nil

您可以在下面找到我用来检索匹配项的完整代码。

extension String {
    func capturedGroupsFull(forRegex regex: String) -> [(String, NSRange)]? {
        let expression: NSRegularExpression
        do {
            expression = try NSRegularExpression(pattern: regex, options: [.caseInsensitive])
        } catch {
            return nil
        }
        let nsString = self as NSString
        let matches = expression.matches(in: self, options: [], range: NSRange(location:0, length: nsString.length))
        guard let match = matches.first else { return nil }
        var results = [(String, NSRange)]()
        for match in matches {
            let range = match.range
            let matchedString = nsString.substring(with: range)
            results.append((matchedString, range))
        }
        return results
    }
}

最佳答案

为什么第一行返回一个匹配项而第二行​​没有匹配项?

正如已经评论过的,NSRegularExpression 适用于 Unicode 代码点,(普通)JavaScript 正则表达式适用于 UTF-16 代码单元。

某些模式,如 "\\ud83d\\udc68",由有效的代理对组成,可以优化为单个 Unicode 代码点 U+1F468,但此功能并不好- 已记录,因此您不应依赖它,如示例 “(\\ud83d[\\udc68])” 中所示。


我建议不要使用 \uhhhh 的代理对,而是使用 \UHHHHHHHH (或 \x{hhhh}) BMP 字符。

let regex1 = "(\\U0001F468)" //or "(\\x{1F468})"
let regex2 = "([\\U0001F468-\\U0001F469])" // or "([\\x{1F468}-\\x{1F469}])"

"👨".capturedGroupsFull(forRegex: regex1)
// -> [(.0 "👨", .1 {0, 2})]
"👨".capturedGroupsFull(forRegex: regex2)
// -> [(.0 "👨", .1 {0, 2})]

最近的 JavaScript 正则表达式接受 u 选项以使其与 Unicode 代码点一起使用,请尝试以下操作:

/(\u{1F468})/u
/([\u{1F468}-\u{1F469}])/u

您可以使用 JavaScript 语法轻松测试正则表达式模式,并将其转换为 NSRegularExpression 语法,将 \u 替换为 \x (并删除//u)。

关于swift - 正则表达式 unicode 在 swift 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49561982/

相关文章:

mysql - MySQL 中不区分大小写的 unicode 排序规则

ios - 使用 swift 在不同的 View Controller 之间切换

ios - 如何将联系人保存到 iOS 中的联系人应用程序中 - Swift

ios - TableViewController 和 NavigationBar

javascript - 正则表达式用 Grails 注释替换 JavaScript 注释

python - 在多个文件中搜索多个正则表达式,然后输出每个匹配项及其各自的文件

regex - 如何用空格替换行内制表符,保持对齐?

unicode - 手动将 unicode 代码点转换为 UTF-8 和 UTF-16

ios - SwiftUI |阻止 TextField 自动随键盘向上移动

python - 读取文件,输出UTF-8/Unicode