swift 中带有 NSRegularExpressions 的可选捕获组
optional capture groups with NSRegularExpressions in swift
我想有多个可选的捕获组,我想访问它们对应的字符串。
looks/works 喜欢这样的东西:
let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = NSRegularExpression(pattern: "(foo)? (bar)")
for (first?, second) in regex.matches(in:text1) {
print(first) // foo
print(second) // bar
}
for (first?, second) in regex.matches(in:text2) {
print(first) // nil
print(second) // bar
}
使用 NSRegularExpression
检索捕获的潜台词并不容易。
首先,matches(in:range:)
的结果是[NSTextCheckingResult]
,每个NSTextCheckingResult
都没有匹配到像(first?, second)
这样的元组。
如果要检索捕获的潜台词,需要使用rangeAt(_:)
方法从NSTextCheckingResult
获取范围。 rangeAt(0)
表示匹配整个模式的范围,rangeAt(1)
表示第一次捕获,rangeAt(2)
表示第二次,以此类推。
和rangeAt(_:)
returns一个NSRange
,而不是SwiftRange
。内容(location
和 length
)基于 NSString
.
的 UTF-16 表示
这是对您的目的最重要的部分,rangeAt(_:)
returns NSRange(location: NSNotFound, length: 0)
对于每个丢失的捕获。
所以,你可能需要这样写:
let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = try! NSRegularExpression(pattern: "(?:(foo).*)?(bar)") //please find a better example...
for match in regex.matches(in: text1, range: NSRange(0..<text1.utf16.count)) {
let firstRange = match.rangeAt(1)
let secondRange = match.rangeAt(2)
let first = firstRange.location != NSNotFound ? (text1 as NSString).substring(with: firstRange) : nil
let second = (text1 as NSString).substring(with: secondRange)
print(first) // Optioonal("foo")
print(second) // bar
}
for match in regex.matches(in: text2, range: NSRange(0..<text2.utf16.count)) {
let firstRange = match.rangeAt(1)
let secondRange = match.rangeAt(2)
let first = firstRange.location != NSNotFound ? (text2 as NSString).substring(with: firstRange) : nil
let second = (text2 as NSString).substring(with: secondRange)
print(first) // nil
print(second) // bar
}
我想有多个可选的捕获组,我想访问它们对应的字符串。
looks/works 喜欢这样的东西:
let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = NSRegularExpression(pattern: "(foo)? (bar)")
for (first?, second) in regex.matches(in:text1) {
print(first) // foo
print(second) // bar
}
for (first?, second) in regex.matches(in:text2) {
print(first) // nil
print(second) // bar
}
使用 NSRegularExpression
检索捕获的潜台词并不容易。
首先,matches(in:range:)
的结果是[NSTextCheckingResult]
,每个NSTextCheckingResult
都没有匹配到像(first?, second)
这样的元组。
如果要检索捕获的潜台词,需要使用rangeAt(_:)
方法从NSTextCheckingResult
获取范围。 rangeAt(0)
表示匹配整个模式的范围,rangeAt(1)
表示第一次捕获,rangeAt(2)
表示第二次,以此类推。
和rangeAt(_:)
returns一个NSRange
,而不是SwiftRange
。内容(location
和 length
)基于 NSString
.
这是对您的目的最重要的部分,rangeAt(_:)
returns NSRange(location: NSNotFound, length: 0)
对于每个丢失的捕获。
所以,你可能需要这样写:
let text1 = "something with foo and bar"
let text2 = "something with just bar"
let regex = try! NSRegularExpression(pattern: "(?:(foo).*)?(bar)") //please find a better example...
for match in regex.matches(in: text1, range: NSRange(0..<text1.utf16.count)) {
let firstRange = match.rangeAt(1)
let secondRange = match.rangeAt(2)
let first = firstRange.location != NSNotFound ? (text1 as NSString).substring(with: firstRange) : nil
let second = (text1 as NSString).substring(with: secondRange)
print(first) // Optioonal("foo")
print(second) // bar
}
for match in regex.matches(in: text2, range: NSRange(0..<text2.utf16.count)) {
let firstRange = match.rangeAt(1)
let secondRange = match.rangeAt(2)
let first = firstRange.location != NSNotFound ? (text2 as NSString).substring(with: firstRange) : nil
let second = (text2 as NSString).substring(with: secondRange)
print(first) // nil
print(second) // bar
}