当没有匹配项或组索引太高时返回 nil
Returning nil when there is no match or group index is too high
我有以下代码(在 Swift 1.2 中),它深受 this tutorial on regex expressions (in particular by the function listGroups
from the there given playground 的启发:
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
函数 return 是与第 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)
不会 return "no capture" 字符串。事实上,它 return 什么都不是。
上面groupMatch
的定义有什么问题?我如何获得预期的行为?
您试图通过访问不存在的组来初始化子字符串。因此,在 if
条件执行之前出现了错误。 Return if
里面的子串:
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)
if groupIndex < match!.numberOfRanges { // RIGHT BELOW \/
return (string as NSString).substringWithRange(match!.rangeAtIndex(groupIndex))
} else {
return nil
}
}
然后,println(grp3cap)
将打印 nil
,println(test(pat, str, 3))
将打印 no capture
。
除了 stribizhev 的回答:修改后的函数 groupMatch
仍然没有执行 post 的标题建议的内容:如果没有匹配,groupMatch
会出错全部。如果我们也想 return 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)
也会产生所需的 "no capture"。
注意:我在 this question 的答案中找到了带有 where
子句的优雅的可选解包。
我有以下代码(在 Swift 1.2 中),它深受 this tutorial on regex expressions (in particular by the function listGroups
from the there given playground 的启发:
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
函数 return 是与第 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)
不会 return "no capture" 字符串。事实上,它 return 什么都不是。
上面groupMatch
的定义有什么问题?我如何获得预期的行为?
您试图通过访问不存在的组来初始化子字符串。因此,在 if
条件执行之前出现了错误。 Return if
里面的子串:
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)
if groupIndex < match!.numberOfRanges { // RIGHT BELOW \/
return (string as NSString).substringWithRange(match!.rangeAtIndex(groupIndex))
} else {
return nil
}
}
然后,println(grp3cap)
将打印 nil
,println(test(pat, str, 3))
将打印 no capture
。
除了 stribizhev 的回答:修改后的函数 groupMatch
仍然没有执行 post 的标题建议的内容:如果没有匹配,groupMatch
会出错全部。如果我们也想 return 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)
也会产生所需的 "no capture"。
注意:我在 this question 的答案中找到了带有 where
子句的优雅的可选解包。