没有匹配或组索引时返回nil太高

时间:2015-08-25 19:30:34

标签: regex swift optional

我有以下代码(在Swift 1.2中),它受到this tutorial on regex expressions的启发(特别是来自给定playground的函数listGroups):

func groupMatch(pattern: String, string: String, groupIndex: Int) -> String? {
    let regex = NSRegularExpression(pattern: pattern, options: nil, error: nil)
    let range = NSMakeRange(0,count(string))
    let match: NSTextCheckingResult? = regex?.firstMatchInString(string, options: nil, range: range)
    let substring: String? = (string as NSString).substringWithRange(match!.rangeAtIndex(groupIndex))
    if groupIndex < match!.numberOfRanges {
        return substring
    } else {
        return nil
    }
}

这个想法是给定一个模式,一个字符串和一个(正)整数n,该函数返回第n组匹配的第一个子字符串(如果存在)。例如,

let pat = "aa\\s*(\\d+)\\.(\\d\\d)"
let str = "aa     1234.56  aa 7.89"

let grp1cap = groupMatch(pat, str, 1) // yields "1234"
let grp2cap = groupMatch(pat, str, 2) // yields "56"

到目前为止一切顺利。但是,groupMatch的定义并不符合我的预期。以下一行

let grp3cap = groupMatch(pat, str, 3)

似乎没有评估为nil。我想测试是否有值,例如像这样

func test(pat: String, str: String, idx: Int) -> String {
    if let cap = groupMatch(pat, str, idx) {
        return cap
    } else {
        return ("no capture")
    }
}

但是test(pat, str, 3)不会返回“no capture”字符串。事实上,它根本不会返回任何内容。

groupMatch的上述定义有什么问题?我如何获得预期的行为?

1 个答案:

答案 0 :(得分:0)

除了stribizhev的答案之外:修改后的函数groupMatch仍然没有执行帖子标题所暗示的内容:groupMatch在完全没有匹配的情况下会出错。如果我们还希望在这种情况下返回nil,我们可以这样做:

func groupMatch(pattern: String, string: String, groupIndex: Int) -> String? {
    let regex = NSRegularExpression(pattern: pattern, options: nil, error: nil)
    let range = NSMakeRange(0,count(string))
    if let match = regex?.firstMatchInString(string, options: nil, range: range) where groupIndex < match.numberOfRanges {
        return (string as NSString).substringWithRange(match.rangeAtIndex(groupIndex))
    } else {
        return nil
    }
}

现在,例如,test(pat,"",0)也会产生所需的“无捕获”。

注意:我在this question的答案中找到了where条款的优雅可选展开。