Почему наличие более одной группы захвата в моем регулярном выражении приводит к сбою моего приложения?

Независимо от регулярного выражения >1 группа захвата приведет к сбою этого кода со следующей ошибкой.

Приложение завершает работу из-за необработанного исключения «NSRangeException», причина: «-[__NSCFString substringWithRange:]: диапазон {9223372036854775807, 0} выходит за пределы; длина строки 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"]) 
    }
}

}


person Declan McKenna    schedule 15.02.2016    source источник
comment
let nsString = self as NSString Является ли self строкой?   -  person tktsubota    schedule 15.02.2016
comment
@TroyT Да, это расширение строки. Я расширю код, чтобы показать это.   -  person Declan McKenna    schedule 15.02.2016
comment
@DavidS изменился, не мог найти слов для того, что происходило, поэтому предыдущее предложение было всего на один шаг лучше, чем «Halp».   -  person Declan McKenna    schedule 15.02.2016


Ответы (1)


Range {9223372036854775807, 0} равно {NSNotFound, 0}, значит совпадения нет.

Из документации

Некоторые регулярные выражения (но не пример шаблона) могут успешно сопоставляться с диапазоном нулевой длины, поэтому сравнение полученного диапазона с {NSNotFound, 0} является наиболее надежным способом определить, было ли совпадение или нет.

Реализовать проверку в enumerateMatchesInString например

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)
    }
}
person vadian    schedule 15.02.2016
comment
Я не думаю, что это возможно. Я использую следующее регулярное выражение, и \\d{7,10} для обеих групп захвата должны предотвратить это. regex101.com/r/cN6dC7/33 - person Declan McKenna; 15.02.2016
comment
Эта ошибка возникает только при наличии › 1 группы захвата. - person Declan McKenna; 16.02.2016
comment
Просто проверьте этот диапазон NSNotFound в цикле перечисления, чтобы избежать сбоя. - person vadian; 16.02.2016
comment
Как мне сделать сравнение? Беру ли я substringWithRange(result!.rangeAtIndex(captureGroup)) для сравнения или мне следует искать свойство 'theResult'? - person Declan McKenna; 16.02.2016
comment
Спасибо, извините за просьбу о кормлении с ложки, я никогда раньше не использовал блоки в Swift. Ваше форматирование делает роль «в» намного яснее. - person Declan McKenna; 16.02.2016