Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
Add capturedRanges to Match
Browse files Browse the repository at this point in the history
  • Loading branch information
hectr committed Mar 28, 2020
1 parent 7389e00 commit 05c9759
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
6 changes: 4 additions & 2 deletions Sources/RegexMatcher/Match.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ public struct Match: Equatable {

public let range: Range<String.Index>
public let value: String

init(range: Range<String.Index>, in string: String) {
public let capturedRanges: [Range<String.Index>?]

init(range: Range<String.Index>, capturedRanges: [Range<String.Index>?], in string: String) {
self.range = range
self.value = String(string[range.lowerBound..<range.upperBound])
self.capturedRanges = capturedRanges
}
}
20 changes: 14 additions & 6 deletions Sources/RegexMatcher/Regex.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,22 @@ public struct Regex: Equatable {
let results = self.textCheckingResults(in: string)
var matches = [Match]()
for result in results {
if let range = string.range(from: result.range) {
let match = Match(range: range, in: string)
matches.append(match)
} else {
assert(false)
guard let range = string.range(from: result.range) else {
assertionFailure()
continue
}
var capturedRanges = [Range<String.Index>?]()
for captureGroupIndex in 1 ..< result.numberOfRanges {
let nsRange = result.range(at: captureGroupIndex)
let range = string.range(from: nsRange)
capturedRanges.append(range)
}
let match = Match(range: range,
capturedRanges: capturedRanges,
in: string)
matches.append(match)
}

return matches
}

Expand Down
8 changes: 4 additions & 4 deletions Tests/RegexMatcherTests/MatchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MatchTests: XCTestCase {
string = "some string"
substring = "e s"
range = string.range(of: substring)
sut = Match(range: range, in: string)
sut = Match(range: range, capturedRanges: [], in: string)
}

func testRangeIsInitialized() {
Expand All @@ -46,23 +46,23 @@ class MatchTests: XCTestCase {
let otherString = "mose sgnirt"
let otherSubstring = "e s"
let otherRange = otherString.range(of: otherSubstring)
let otherMatch = Match(range: otherRange!, in: otherString)
let otherMatch = Match(range: otherRange!, capturedRanges: [], in: otherString)
XCTAssertEqual(sut, otherMatch)
}

func testEqualityReturnsFalseWhenRangesDiffer() {
let otherString = "se sg"
let otherSubstring = "e s"
let otherRange = otherString.range(of: otherSubstring)
let otherMatch = Match(range: otherRange!, in: otherString)
let otherMatch = Match(range: otherRange!, capturedRanges: [], in: otherString)
XCTAssertNotEqual(sut, otherMatch)
}

func testEqualityReturnsFalseWhenValuesDiffer() {
let otherString = "emos gnirts"
let otherSubstring = "s g"
let otherRange = otherString.range(of: otherSubstring)
let otherMatch = Match(range: otherRange!, in: otherString)
let otherMatch = Match(range: otherRange!, capturedRanges: [], in: otherString)
XCTAssertNotEqual(sut, otherMatch)
}

Expand Down
13 changes: 13 additions & 0 deletions Tests/RegexMatcherTests/RegexTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ class RegexTests: XCTestCase {
XCTAssertEqual(values, expectedValues)
}

func testMatchesWithCapturingGroups() {
sut = "([a-z]([a-z]) )"
let expectedGroups = ["me ", "e"]
let string = "some string"
let matches = sut.matches(in: string)
let capturedGroups = matches
.flatMap { $0.capturedRanges }
.compactMap { $0 }
.map { String(string[$0]) }
XCTAssertEqual(capturedGroups, expectedGroups)
}

func testMatchesWithOptions() {
sut = try! Regex(pattern: pattern, options: [.dotMatchesLineSeparators])
let expectedValues = ["som", "e s", "tri", "ng\n", "som", "e s", "tri"]
Expand Down Expand Up @@ -114,6 +126,7 @@ class RegexTests: XCTestCase {
("testExpressibleByStringLiteralConformance", testExpressibleByStringLiteralConformance),
("testMatches", testMatches),
("testMatchesWithOptions", testMatchesWithOptions),
("testMatchesWithCapturingGroups", testMatchesWithCapturingGroups),
("testNumberOfMatches", testNumberOfMatches),
("testNumberOfMatchesWithOptions", testNumberOfMatchesWithOptions)
]
Expand Down

0 comments on commit 05c9759

Please sign in to comment.