How to avoid an error due to special characters in search string when using Regex for a simple search in Swift?

谁说我不能喝 提交于 2019-12-31 02:54:27

问题


I'm using Regex to search for a word in a textView. I implemented a textField and two switch as options (Whole words and Match case). All work fine when you enter a plain word in the search filed but I get an error when I enter a special character like \ or *.

The error I get is like this one:

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

Is there a way to avoid this problem and have the code handle all the text like plain text?

Because I would like to search also for special characters, I would like to prefer to not interdict to enter them. At the beginning I though to programmatically add an escape backslash to all special character before to perform a search, but maybe there are some more smart approaches?

Here is the code I'm using (based on this tutorial: 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:


You may use NSRegularExpression.escapedPatternForString:

Returns a string by adding backslash escapes as necessary to protect any characters that would match as pattern metacharacters.

Thus, you need

var pattern = NSRegularExpression.escapedPatternForString(searchString)

Also, note that this piece:

if isWholeWords {
    pattern = "\\b\(searchString)\\b"

might fail if a user inputs (text) and wishes to search for it as a whole word. The best way to match whole words is by means of lookarounds disallowing word chars on both ends of the search word:

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


来源:https://stackoverflow.com/questions/38375557/how-to-avoid-an-error-due-to-special-characters-in-search-string-when-using-rege

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!