我正在尝试匹配用户输入中的粗鲁单词,例如“我恨你!”或“i.håté.Yoù”将与从JSON解析的单词数组中的“恨你”匹配。
因此,我需要对大小写和变音符号不敏感,并将粗鲁单词中的空格视为任何非字母字符:
正则表达式元字符\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
}
}
这对任何一个元字符都不起作用,我想它们不是由
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
}
}
这似乎可以正常工作,但是我不知道使正则表达式变音符号不敏感,所以我尝试了这一点(以及其他解决方案,例如重新编码)
let text = text.stringByFoldingWithOptions(.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
但是,这对我不起作用,因为每次输入字符时都会检查用户输入,因此我尝试去除重音符号的所有解决方案都使该应用程序非常慢。
有人知道是否还有其他解决方案,或者我使用的方法是否错误?
谢谢
编辑
我实际上弄错了,导致应用程序变慢的原因是尝试与
\P{L}
匹配,我尝试了第二个解决方案与\W
和带重音符号的行,现在即使与少于我想要的字符串匹配的字符串也可以正常工作。链接
这些可能会帮助某些处理正则表达式和谓词的人:
最佳答案
朝着不同的方向去也许是值得的。除了更改输入量之外,如果更改了正则表达式该怎么办?
例如,可以与hate.you
匹配,而不是与[h][åæaàâä][t][ëèêeé].[y][o0][ùu]
匹配(无论如何,它都不是完整的列表)。快速进行此转换(不存储它)将是最有意义的,因为如果您需要将字符扩展到以后的内容,则转换可能会更容易。
这将使您对要匹配的字符有更多的控制。如果您看的话,我有0
作为与o
匹配的字符。没有多少Unicode强制可以让您做到这一点。