Skip to content

Commit

Permalink
Make RegexMatch iterable
Browse files Browse the repository at this point in the history
don't forget to pass the state
add length and eltype to RegexMatch
Fix missing enumerate
=update news for RegexMatch iterating

fix typo in news

Co-authored-by: Curtis Vogt <curtis.vogt@gmail.com>

remove example of possible use from NEWS.md

Remove stray at-test
  • Loading branch information
oxinabox committed Jan 19, 2021
1 parent 33573ec commit c8f18a6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Standard library changes
* `escape_string` can now receive a collection of characters in the keyword
`keep` that are to be kept as they are. ([#38597]).
* `getindex` can now be used on `NamedTuple`s with multiple values ([#38878])
* `RegexMatch` now iterate to give their captures. ([#34355]).

#### Package Manager

Expand Down
10 changes: 7 additions & 3 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,13 @@ function show(io::IO, m::RegexMatch)
idx_to_capture_name = PCRE.capture_names(m.regex.regex)
if !isempty(m.captures)
print(io, ", ")
for i = 1:length(m.captures)
for (i, capture) in enumerate(m)
# If the capture group is named, show the name.
# Otherwise show its index.
capture_name = get(idx_to_capture_name, i, i)
print(io, capture_name, "=")
show(io, m.captures[i])
if i < length(m.captures)
show(io, capture)
if i < length(m)
print(io, ", ")
end
end
Expand All @@ -185,6 +185,10 @@ function haskey(m::RegexMatch, name::Symbol)
end
haskey(m::RegexMatch, name::AbstractString) = haskey(m, Symbol(name))

iterate(m::RegexMatch, args...) = iterate(m.captures, args...)
length(m::RegexMatch) = length(m.captures)
eltype(m::RegexMatch) = eltype(m.captures)

function occursin(r::Regex, s::AbstractString; offset::Integer=0)
compile(r)
return PCRE.exec_r(r.regex, String(s), offset, r.match_options)
Expand Down
18 changes: 18 additions & 0 deletions test/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,24 @@
@test r"this|that"^2 == r"(?:this|that){2}"
end

@testset "iterate" begin
m = match(r"(.) test (.+)", "a test 123")
@test first(m) == "a"
@test collect(m) == ["a", "123"]
for (i, capture) in enumerate(m)
i == 1 && @test capture == "a"
i == 2 && @test capture == "123"
end
end

@testset "Destructuring dispatch" begin
handle(::Nothing) = "not found"
handle((capture,)::RegexMatch) = "found $capture"

@test handle(match(r"a (\d)", "xyz")) == "not found"
@test handle(match(r"a (\d)", "a 1")) == "found 1"
end

# Test that PCRE throws the correct kind of error
# TODO: Uncomment this once the corresponding change has propagated to CI
#@test_throws ErrorException Base.PCRE.info(C_NULL, Base.PCRE.INFO_NAMECOUNT, UInt32)
Expand Down

0 comments on commit c8f18a6

Please sign in to comment.