我有以下代码(在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
的上述定义有什么问题?我如何获得预期的行为?
答案 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
条款的优雅可选展开。