Return loop index in regex iterator.

This commit is contained in:
Jeroen van Rijn
2025-04-06 21:45:37 +02:00
parent 66077add33
commit 9a2b6c01aa
2 changed files with 15 additions and 6 deletions

View File

@@ -73,6 +73,7 @@ Match_Iterator :: struct {
offset: int,
regex: Regular_Expression,
capture: Capture,
idx: int,
temp: runtime.Allocator,
}
@@ -442,7 +443,7 @@ Returns:
- result: `Capture` for this iteration.
- ok: A bool indicating if there was a match, stopping the iteration on `false`.
*/
match_iterator :: proc(it: ^Match_Iterator) -> (result: Capture, ok: bool) {
match_iterator :: proc(it: ^Match_Iterator) -> (result: Capture, index: int, ok: bool) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
num_groups: int
num_groups, ok = match_with_preallocated_capture(
@@ -452,6 +453,10 @@ match_iterator :: proc(it: ^Match_Iterator) -> (result: Capture, ok: bool) {
it.temp,
)
defer if ok {
it.idx += 1
}
if num_groups > 0 {
for i in 0..<num_groups {
it.capture.pos[i] += it.offset
@@ -459,7 +464,7 @@ match_iterator :: proc(it: ^Match_Iterator) -> (result: Capture, ok: bool) {
it.offset = it.capture.pos[0][1]
result = {it.capture.pos[:num_groups], it.capture.groups[:num_groups]}
}
return
return result, it.idx, ok
}
match :: proc {
@@ -468,6 +473,11 @@ match :: proc {
match_iterator,
}
reset :: proc(it: ^Match_Iterator) {
it.offset = 0
it.idx = 0
}
/*
Allocate a `Capture` in advance for use with `match`. This can save some time
if you plan on performing several matches at once and only need the results

View File

@@ -1127,13 +1127,12 @@ test_match_iterator :: proc(t: ^testing.T) {
(err == nil) or_continue
count: int
for capture in regex.match(&it) {
for capture, idx in regex.match(&it) {
if count > len(test.expected) {
break
}
check_capture(t, capture, test.expected[count])
count += 1
check_capture(t, capture, test.expected[idx])
}
testing.expect_value(t, count, len(test.expected))
testing.expect_value(t, it.idx, len(test.expected))
}
}