Skip to content

Commit

Permalink
Make RegexMatch iterable (JuliaLang#34355)
Browse files Browse the repository at this point in the history
add iterate, length, and eltype to RegexMatch

Co-authored-by: Curtis Vogt <curtis.vogt@gmail.com>
  • Loading branch information
2 people authored and ElOceanografo committed May 4, 2021
1 parent a3ab338 commit ddcf03b
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 1 deletion.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Standard library changes
`keep` that are to be kept as they are. ([#38597]).
* `getindex` can now be used on `NamedTuple`s with multiple values ([#38878])
* `keys(::RegexMatch)` is now defined to return the capture's keys, by name if named, or by index if not ([#37299]).
* `RegexMatch` now iterate to give their captures. ([#34355]).

#### Package Manager

Expand Down
6 changes: 5 additions & 1 deletion base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function show(io::IO, m::RegexMatch)
for (i, capture_name) in enumerate(capture_keys)
print(io, capture_name, "=")
show(io, m.captures[i])
if i < length(m.captures)
if i < length(m)
print(io, ", ")
end
end
Expand All @@ -190,6 +190,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 @@ -167,6 +167,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 ddcf03b

Please sign in to comment.