Reputation: 3092
I'm using Regex to search in a textView. All works fine with simple strings but when I try to enter only a part of a regular expression operator I get a cash with the error:
Error Domain=NSCocoaErrorDomain Code=2048 "The value “\” is invalid." UserInfo={NSInvalidValue=\}
For example if I enter "\n" it works, but if I enter only "\" (without quotes), I get the crash. What I can't get to do is to find a way to check the expression before to use it.
I'm using this code partially based on this tutorial and this answer by Wiktor Stribiżew:
extension NSRegularExpression {
convenience init?(options: SearchOptions) {
let searchString = options.searchString
let isCaseSensitive = options.matchCase // set to true
let isWholeWords = options.wholeWords // set to false
let escapeMetacharacters = options.escapeMetacharacters // set to false
// 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 isWholeWords {
pattern = "(?<!\\w)" + NSRegularExpression.escapedPatternForString(searchString) + "(?!\\w)"
}
do {
try self.init(pattern: pattern, options: regexOption)
} catch {
print(error)
}
}
}
Upvotes: 1
Views: 1544
Reputation: 47876
The first code below have shown unstable behaviour and you should not use it. (Please see the latter part of this answer.)
Add one line to your failable initializer:
do {
try self.init(pattern: pattern, options: regexOption)
} catch {
print(error)
return nil //->you need to return nil to tell initialization failed
}
(I think Swift compiler should warn about this missing return nil
. May be a bug of Swift?)
After that you can safely check the result if it's nil or not:
let sOpts = SearchOptions(searchString: "\\", replacementString: "", matchCase: false, wholeWords: false)
if let regex = NSRegularExpression(options: sOpts) {
//Use regex
print(regex)
} else {
//Process errors
print("Something bad in SearchOptions")
}
(I omitted escapeMetacharacters
, as it's not used yet.)
As far as I tested, using static method has never crashed.
extension NSRegularExpression {
static func expresssionWith(options: SearchOptions) -> NSRegularExpression? {
let searchString = options.searchString
let isCaseSensitive = options.matchCase // set to true
let isWholeWords = options.wholeWords // set to false
// 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 isWholeWords {
pattern = "(?<!\\w)" + NSRegularExpression.escapedPatternForString(searchString) + "(?!\\w)"
}
do {
return try NSRegularExpression(pattern: pattern, options: regexOption)
} catch {
print(error)
return nil
}
}
}
let sOpts = SearchOptions(searchString: "\\", replacementString: "", matchCase: false, wholeWords: false)
if let regex = NSRegularExpression.expresssionWith(sOpts) {
//Use regex
print(regex)
} else {
//Process errors
print("Something bad in SearchOptions")
}
Upvotes: 1