问题
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