在Swift中使用Regex进行简单搜索时,如何避免因搜索字符串中的特殊字符而导致的错误?

时间:2016-07-14 13:26:54

标签: ios regex swift uitextview

我正在使用Regex在textView中搜索单词。我实现了textField和两个switch作为选项(整个单词和匹配大小写)。当您在搜索字段中输入普通单词时,所有工作都正常,但是当我输入特殊字符(如\或*)时出现错误。

我得到的错误就像这样:

Error Domain=NSCocoaErrorDomain Code=2048 "The value “*” is invalid." UserInfo={NSInvalidValue=*}

有没有办法避免这个问题并让代码处理所有文本,如纯文本?

因为我也想搜索特殊字符,所以我宁愿不禁止输入它们。在开始时我想以编程方式在执行搜索之前为所有特殊字符添加一个转义反斜杠,但也许有一些更聪明的方法?

以下是我正在使用的代码(基于本教程:NSRegularExpression Tutorial: Getting Started

struct SearchOptions {
    let searchString: String
    var replacementString: String
    let matchCase: Bool
    let wholeWords: Bool
}

extension NSRegularExpression {
    convenience init?(options: SearchOptions) {
        let searchString = options.searchString
        let isCaseSensitive = options.matchCase
        let isWholeWords = options.wholeWords

        // handle case sensitive option
        var regexOption: NSRegularExpressionOptions = .CaseInsensitive
        if isCaseSensitive { // if it is match case remove case sensitive option
            regexOption = []
        }

        // put the search string in the pattern
        var pattern = searchString
        // if it's whole word put the string between word boundary \b
        if isWholeWords {
            pattern = "\\b\(searchString)\\b" // the second \ is used as escape
        }

        do {
            try self.init(pattern: pattern, options: regexOption)
        } catch {
            print(error)
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您可以使用NSRegularExpression.escapedPatternForString

  

通过添加反斜杠转义符来返回一个字符串,以保护任何与模式元字符匹配的字符。

因此,你需要

var pattern = NSRegularExpression.escapedPatternForString(searchString)

另外,请注意这篇文章:

if isWholeWords {
    pattern = "\\b\(searchString)\\b"
如果用户输入(text)并希望将其作为整个单词进行搜索,则

可能会失败。匹配整个单词的最佳方法是通过在搜索词的两端禁止单词字符的外观:

if isWholeWords {
    pattern = "(?<!\\w)" + NSRegularExpression.escapedPatternForString(searchString) + "(?!\\w)"