Skip to content

Commit 49820f0

Browse files
committed
bugfix and test
1 parent 68c1537 commit 49820f0

File tree

4 files changed

+33
-7
lines changed

4 files changed

+33
-7
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,26 @@ have otherwise used `String`.
1313
(In particular, as much as possible we try to implement efficient copy-free
1414
`String`-like operations on `StringView`, such as iteration and regular-expression
1515
searching, as long as the underlying `UInt8` array is a contiguous dense array.)
16+
17+
For example:
18+
19+
```jl
20+
julia> b = [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
21+
22+
julia> s = StringView(b) # does not make a copy
23+
"foobar"
24+
25+
julia> collect(eachmatch(r"[aeiou]+", s))
26+
2-element Array{RegexMatch,1}:
27+
RegexMatch("oo")
28+
RegexMatch("a")
29+
30+
julia> StringView(@view b[1:3]) # also works for subarrays, with no copy
31+
"foo"
32+
33+
julia> abc = StringView(0x61:0x63) # and for other array types
34+
"abc"
35+
```
36+
37+
Other optimized (copy-free) operations include I/O, hashing, iteration/indexing,
38+
comparisons, and validation.

src/StringViews.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ write(io::IO, s::StringView) = write(io, s.data)
8080
print(io::IO, s::StringView) = (write(io, s); nothing)
8181

8282
Base.@propagate_inbounds Base.thisind(s::StringView, i::Int) = Base._thisind_str(s, i)
83-
Base.@propagate_inbounds Base.nextind(s::String, i::Int) = Base._nextind_str(s, i)
83+
Base.@propagate_inbounds Base.nextind(s::StringView, i::Int) = Base._nextind_str(s, i)
8484
Base.isvalid(s::StringView, i::Int) = checkbounds(Bool, s, i) && thisind(s, i) == i
8585

8686
function Base.hash(s::DenseStringView, h::UInt)

src/regex.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ struct RegexMatchIterator{T<:DenseStringView}
6969
string::T
7070
overlap::Bool
7171
end
72-
RegexMatchIterator(regex::Regex, string::T, ovr::Bool=false) where {T<:DenseStringView} = RegexMatchIterator{T}(regex, string, ovr)
7372
Base.compile(itr::RegexMatchIterator) = (compile(itr.regex); itr)
74-
Base.eltype(::Type{RegexMatchIterator}) = RegexMatch
75-
Base.IteratorSize(::Type{RegexMatchIterator}) = Base.SizeUnknown()
73+
Base.eltype(::Type{<:RegexMatchIterator}) = RegexMatch
74+
Base.IteratorSize(::Type{<:RegexMatchIterator}) = Base.SizeUnknown()
7675

7776
function Base.iterate(itr::RegexMatchIterator, (offset,prevempty)=(1,false))
7877
opts_nonempty = UInt32(PCRE.ANCHORED | PCRE.NOTEMPTY_ATSTART)
@@ -109,9 +108,9 @@ Base.eachmatch(re::Regex, str::DenseStringView; overlap = false) =
109108

110109
# copied from julia/base/pcre.jl:
111110
function PCRE.exec(re, subject::DenseStringView, offset, options, match_data)
112-
rc = ccall((:pcre2_match_8, PCRE_LIB), Cint,
111+
rc = ccall((:pcre2_match_8, PCRE.PCRE_LIB), Cint,
113112
(Ptr{Cvoid}, Ptr{UInt8}, Csize_t, Csize_t, UInt32, Ptr{Cvoid}, Ptr{Cvoid}),
114-
re, subject, ncodeunits(subject), offset, options, match_data, get_local_match_context())
113+
re, subject, ncodeunits(subject), offset, options, match_data, PCRE.get_local_match_context())
115114
# rc == -1 means no match, -2 means partial match.
116115
rc < -2 && error("PCRE.exec error: $(err_message(rc))")
117116
return rc >= 0

test/runtests.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,8 @@ abc = StringView(0x61:0x63)
4141

4242
@test Base.print_to_string(s) == "foobar"
4343
@test Base.print_to_string(abc) == "abc"
44-
end
44+
end
45+
46+
@testset "regular expressions" begin
47+
@test [m.match for m in collect(eachmatch(r"[aeiou]+", s))] == ["oo", "a"]
48+
end

0 commit comments

Comments
 (0)