2016-12-03 5 views
0

선택적 일 수있는 캡처 그룹을 여러 개 갖고 싶습니다. 해당 그룹에 해당하는 문자열에 액세스하려고합니다./보이는NSRegularExpressions가있는 캡처 그룹 (선택 사항)

뭔가는 다음과 같이 작동합니다 NSRegularExpression로 촬영 한 서브 텍스트를 가져

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 
} 

답변

1

그렇게 쉬운 일이 아닙니다. 모든

첫째, matches(in:range:)의 결과는 [NSTextCheckingResult]이며, 각 NSTextCheckingResult(first?, second) 같은 튜플과 일치하지 않습니다.

캡쳐 된 하위 텍스트를 검색하려면 NSTextCheckingResult에서 rangeAt(_:) 방법으로 범위를 가져와야합니다. rangeAt(0)은 전체 패턴과 일치하는 범위를 나타내며 첫 번째 캡처는 rangeAt(1)이고 두 번째 패턴은 rangeAt(2)입니다.

그리고 rangeAt(_:)Range이 아닌 NSRange을 반환합니다. 콘텐츠 (locationlength)는 NSString의 UTF-16 표현을 기반으로합니다.

그리고 가장 중요한 부분 인 rangeAt(_:)은 누락 된 각 캡처에 대해 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 
} 
:

그래서, 당신은 다음처럼 작성할 필요가 있습니다