Why does having more than one capture group in my regex crash my app?

爷,独闯天下 提交于 2019-12-11 02:17:42

问题


Regardless of what the regex is, >1 capture group will crash this code with the following error.

Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range {9223372036854775807, 0} out of bounds; string length 279'

public extension String
{
    //Multi use parsing function
    func regexParse(pattern:String, captureGroup:Int, caseSensitive:Bool) ->[String]
    {
        do
        {
            //Creates empty results array.
            var resultsArray = [""]

        //Sets Case sensitivity
        var caseSensitivity = NSRegularExpressionOptions.CaseInsensitive
        if(caseSensitive)
        {
            caseSensitivity = NSRegularExpressionOptions.init(rawValue: 0)
        }

        //Sets regex to correct pattern
        let regex = try NSRegularExpression(pattern: pattern, options: caseSensitivity)
        //Converts string to NSString as swift doesn't support regex
        let nsString = self as NSString

        //Sets parsing range to the entire string
        let all = NSMakeRange(0, nsString.length)

        //Enumerates through all matches and extracts the 1st capture bracket for each match and adds it to the resultsArray.

            regex.enumerateMatchesInString(self, options: NSMatchingOptions(rawValue: 0), range: all)
                {
                    (result: NSTextCheckingResult?, _, _) in let theResult = nsString.substringWithRange(result!.rangeAtIndex(captureGroup))
                    resultsArray.append(theResult)
            } //!!>>>>>>>>Error occurs here after skipping MatchingOptions content.!!
            return resultsArray

    }
    catch
    {
        print("Invalid regex")
        return(["Error"]) 
    }
}

}


回答1:


Range {9223372036854775807, 0} is {NSNotFound, 0}, that means there is no match.

From the documentation

Some regular expressions (though not the example pattern) can successfully match a zero-length range, so the comparison of the resulting range with {NSNotFound, 0} is the most reliable way to determine whether there was a match or not

Implement a check in enumerateMatchesInString for example

regex.enumerateMatchesInString(self, options: [], range: all) { (result: NSTextCheckingResult?, _, _) in
    let capturedRange = result!.rangeAtIndex(captureGroup)
    if !NSEqualRanges(capturedRange, NSMakeRange(NSNotFound, 0)) {
       let theResult = nsString.substringWithRange(capturedRange)
       resultsArray.append(theResult)
    }
}


来源:https://stackoverflow.com/questions/35415678/why-does-having-more-than-one-capture-group-in-my-regex-crash-my-app

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