Swift中正则表达式与元字符的case和变音符号不敏感匹配

Cyr*_*ind 7 regex nspredicate nsregularexpression swift

我试图在用户输入中匹配粗鲁的单词,例如"我讨厌你!" 或者"i.håté.Yoù"将与从JSON解析的单词数组中的"恨你"相匹配.

所以我需要它是case和diacritic不敏感的,并将粗鲁的单词中的空格视为任何非字母字符:正则表达式元字符\P{L}应该适用于此,或者至少\W

现在我知道[cd]合作NSPredicate,像这样:

 func matches(text: String) -> [String]? {
        if  let rudeWords = JSON?["words"] as? [String]{
            return rudeWords.filter {
                let pattern = $0.stringByReplacingOccurrencesOfString(" ", withString: "\\P{L}", options: .CaseInsensitiveSearch)
                    return NSPredicate(format: "SELF MATCHES[cd] %@", pattern).evaluateWithObject(text)
            }
        } else {
            log.debug("error fetching rude words")
            return nil
        }
    }
Run Code Online (Sandbox Code Playgroud)

这不适用于任何元字符,我猜他们没有被解析NSpredicate,所以我尝试使用NSRegularExpression这样:

func matches(text: String) -> [String]? {
        if  let rudeWords = JSON?["words"] as? [String]{
            return rudeWords.filter {
                do {
                    let pattern = $0.stringByReplacingOccurrencesOfString(" ", withString: "\\P{L}", options: .CaseInsensitiveSearch)
                    let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
                    return regex.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count)).count > 0
                }
                catch _ {
                    log.debug("error parsing rude word regex")
                    return false
                }
            }
        } else {
            log.debug("error fetching rude words")
            return nil
        }
    }
Run Code Online (Sandbox Code Playgroud)

这似乎工作正常,但我不知道如何使正则表达式变音不敏感,所以我尝试了这个(以及其他解决方案,如重新编码)

let text = text.stringByFoldingWithOptions(.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
Run Code Online (Sandbox Code Playgroud)

但是,这对我来说不起作用,因为我每次输入一个字符时都会检查用户输入,所以我尝试删除重音的所有解决方案都会使应用程序变得非常慢.

有人知道是否有其他解决方案,或者我是否使用了错误的方法?

谢谢

编辑

我实际上错了,使应用程序缓慢的原因是试图匹配\P{L},我尝试了第二个解决方案,\W并使用重点剥离线,现在它工作正常,即使它匹配少于我最初想要的字符串.

链接

这些可能会帮助一些处理正则表达式和谓词的人:

Lau*_*rel 2

朝不同的方向前进可能是值得的。如果您更改正则表达式,而不是展平输入,会怎样?

\n\n

可以匹配hate.you,而不是匹配[h][\xc3\xa5\xc3\xa6a\xc3\xa0\xc3\xa2\xc3\xa4][t][\xc3\xab\xc3\xa8\xc3\xaae\xc3\xa9].[y][o0][\xc3\xb9u](无论如何,它都不是一个完整的列表)。即时进行此转换(而不是存储它)是最有意义的,因为如果您需要稍后更改字符扩展的内容,可能会更容易。

\n\n

这将使您能够更好地控制要匹配的字符。如果你看的话,我有0一个字符匹配o。再多的 Unicode 强制也无法让您做到这一点。

\n