Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,9 @@ This section lists changes that do not have deprecation warnings.
and higher-dimensional arrays instead of linear indices as was previously the case.
Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices.

* The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`,
* The `find*` functions, i.e. `findnext`, `findprev`, `findfirst`,
and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather
than 0 ([#25472], [#25662]).
than `0` or `0:-1` ([#25472], [#25662], [#26149])

* The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the
number of dimensions, which must correspond to the length of the tuple returned by
Expand Down Expand Up @@ -1388,3 +1388,4 @@ Command-line option changes
[#25998]: https://github.com/JuliaLang/julia/issues/25998
[#26009]: https://github.com/JuliaLang/julia/issues/26009
[#26071]: https://github.com/JuliaLang/julia/issues/26071
[#26149]: https://github.com/JuliaLang/julia/issues/26149
98 changes: 48 additions & 50 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -711,10 +711,10 @@ end
@deprecate charwidth textwidth

@deprecate find(x::Number) findall(!iszero, x)
@deprecate findnext(A, v, i::Integer) findnext(equalto(v), A, i)
@deprecate findfirst(A, v) findfirst(equalto(v), A)
@deprecate findprev(A, v, i::Integer) findprev(equalto(v), A, i)
@deprecate findlast(A, v) findlast(equalto(v), A)
@deprecate findnext(A, v, i::Integer) coalesce(findnext(equalto(v), A, i), 0)
@deprecate findfirst(A, v) coalesce(findfirst(equalto(v), A), 0)
@deprecate findprev(A, v, i::Integer) coalesce(findprev(equalto(v), A, i), 0)
@deprecate findlast(A, v) coalesce(findlast(equalto(v), A), 0)
# to fix ambiguities introduced by deprecations
findnext(pred::Function, A, i::Integer) = invoke(findnext, Tuple{Function, Any, Any}, pred, A, i)
findprev(pred::Function, A, i::Integer) = invoke(findprev, Tuple{Function, Any, Any}, pred, A, i)
Expand Down Expand Up @@ -1182,52 +1182,50 @@ end
@deprecate_binding HasOrder Ordered
@deprecate_binding ArithmeticOverflows ArithmeticWraps

@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) findnext(re, str, idx)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) findnext(r, s, idx)
@deprecate search(s::AbstractString, r::Regex) findfirst(r, s)
@deprecate search(s::AbstractString, c::Char, i::Integer) findnext(equalto(c), s, i)
@deprecate search(s::AbstractString, c::Char) findfirst(equalto(c), s)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) findnext(equalto(b), a, i)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) findfirst(equalto(b), a)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) findnext(equalto(b), unsafe_wrap(Vector{UInt8}, a), i)
@deprecate search(a::String, b::Union{Int8,UInt8}) findfirst(equalto(b), unsafe_wrap(Vector{UInt8}, a))
@deprecate search(a::ByteArray, b::Char, i::Integer) findnext(equalto(UInt8(b)), a, i)
@deprecate search(a::ByteArray, b::Char) findfirst(equalto(UInt8(b)), a)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) findnext(occursin(c), s, i)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) findfirst(occursin(c), s)
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) findnext(t, s, i)
@deprecate search(s::AbstractString, t::AbstractString) findfirst(t, s)

@deprecate search(buf::IOBuffer, delim::UInt8) findfirst(equalto(delim), buf)
@deprecate search(buf::Base.GenericIOBuffer, delim::UInt8) findfirst(equalto(delim), buf)

@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) findprev(occursin(c), s, i)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) findlast(occursin(c), s)
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) findprev(t, s, i)
@deprecate rsearch(s::AbstractString, t::AbstractString) findlast(t, s)
@deprecate rsearch(s::ByteArray, t::ByteArray, i::Integer) findprev(t, s, i)
@deprecate rsearch(s::ByteArray, t::ByteArray) findlast(t, s)

@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) findprev(re, str, idx)
@deprecate rsearch(str::Union{String,SubString}, re::Regex) findlast(re, str)
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) findprev(r, s, idx)
@deprecate rsearch(s::AbstractString, r::Regex) findlast(r, s)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) findprev(equalto(c), s, i)
@deprecate rsearch(s::AbstractString, c::Char) findlast(equalto(c), s)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) findprev(equalto(b), a, i)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) findprev(equalto(Char(b)), a, i)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) findprev(equalto(UInt8(b)), a, i)

@deprecate searchindex(s::AbstractString, t::AbstractString) first(findfirst(t, s))
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(findnext(t, s, i))
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(findlast(t, s))
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(findprev(t, s, i))

@deprecate searchindex(s::AbstractString, c::Char) findfirst(equalto(c), s)
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) findnext(equalto(c), s, i)
@deprecate rsearchindex(s::AbstractString, c::Char) findlast(equalto(c), s)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) findprev(equalto(c), s, i)
@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findnext(re, str, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) coalesce(findnext(r, s, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex) coalesce(findfirst(r, s), 0:-1)
@deprecate search(s::AbstractString, c::Char, i::Integer) coalesce(findnext(equalto(c), s, i), 0)
@deprecate search(s::AbstractString, c::Char) coalesce(findfirst(equalto(c), s), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(equalto(b), a, i), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) coalesce(findfirst(equalto(b), a), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(equalto(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}) coalesce(findfirst(equalto(b), unsafe_wrap(Vector{UInt8}, a)), 0)
@deprecate search(a::ByteArray, b::Char, i::Integer) coalesce(findnext(equalto(UInt8(b)), a, i), 0)
@deprecate search(a::ByteArray, b::Char) coalesce(findfirst(equalto(UInt8(b)), a), 0)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findnext(occursin(c), s, i), 0)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findfirst(occursin(c), s), 0)
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) coalesce(findnext(t, s, i), 0:-1)
@deprecate search(s::AbstractString, t::AbstractString) coalesce(findfirst(t, s), 0:-1)

@deprecate search(buf::IOBuffer, delim::UInt8) coalesce(findfirst(equalto(delim), buf), 0)
@deprecate search(buf::Base.GenericIOBuffer, delim::UInt8) coalesce(findfirst(equalto(delim), buf), 0)

@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findprev(occursin(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findlast(occursin(c), s), 0)
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) coalesce(findprev(t, s, i), 0:-1)
@deprecate rsearch(s::AbstractString, t::AbstractString) coalesce(findlast(t, s), 0:-1)

@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findprev(re, str, idx), 0:-1)
@deprecate rsearch(str::Union{String,SubString}, re::Regex) coalesce(findlast(re, str), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) coalesce(findprev(r, s, idx), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex) coalesce(findlast(r, s), 0:-1)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) coalesce(findprev(equalto(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Char) coalesce(findlast(equalto(c), s), 0)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(equalto(b), a, i), 0)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(equalto(Char(b)), a, i), 0)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) coalesce(findprev(equalto(UInt8(b)), a, i), 0)

@deprecate searchindex(s::AbstractString, t::AbstractString) first(coalesce(findfirst(t, s), 0:-1))
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findnext(t, s, i), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(coalesce(findlast(t, s), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findprev(t, s, i), 0:-1))

@deprecate searchindex(s::AbstractString, c::Char) coalesce(findfirst(equalto(c), s), 0)
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) coalesce(findnext(equalto(c), s, i), 0)
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(equalto(c), s), 0)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(equalto(c), s, i), 0)

@deprecate ismatch(r::Regex, s::AbstractString) contains(s, r)

Expand Down
7 changes: 5 additions & 2 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,11 @@ function findnext(re::Regex, str::Union{String,SubString}, idx::Integer)
end
opts = re.match_options
compile(re)
PCRE.exec(re.regex, str, idx-1, opts, re.match_data) ?
((Int(re.ovec[1])+1):prevind(str,Int(re.ovec[2])+1)) : (0:-1)
if PCRE.exec(re.regex, str, idx-1, opts, re.match_data)
(Int(re.ovec[1])+1):prevind(str,Int(re.ovec[2])+1)
else
nothing
end
end
findnext(r::Regex, s::AbstractString, idx::Integer) = throw(ArgumentError(
"regex search is only available for the String type; use String(s) to convert"
Expand Down
24 changes: 14 additions & 10 deletions base/strings/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,10 @@ function _search(s::Union{AbstractString,ByteArray},
idx = _searchindex(s,t,i)
if isempty(t)
idx:idx-1
elseif idx > 0
idx:(idx + lastindex(t) - 1)
else
idx:(idx > 0 ? idx + lastindex(t) - 1 : -1)
nothing
end
end

Expand All @@ -230,16 +232,16 @@ Find the next occurrence of `pattern` in `string` starting at position `start`.
`pattern` can be either a string, or a regular expression, in which case `string`
must be of type `String`.

The return value is a range of indexes where the matching sequence is found, such that
The return value is a range of indices where the matching sequence is found, such that
`s[findnext(x, s, i)] == x`:

`findnext("substring", string, i)` = `start:end` such that
`string[start:end] == "substring"`, or `0:-1` if unmatched.
`string[start:end] == "substring"`, or `nothing` if unmatched.

# Examples
```jldoctest
julia> findnext("z", "Hello to the world", 1)
0:-1
julia> findnext("z", "Hello to the world", 1) === nothing
true

julia> findnext("o", "Hello to the world", 6)
8:8
Expand Down Expand Up @@ -392,8 +394,10 @@ function _rsearch(s::Union{AbstractString,ByteArray},
idx = _rsearchindex(s,t,i)
if isempty(t)
idx:idx-1
elseif idx > 0
idx:(idx + lastindex(t) - 1)
else
idx:(idx > 0 ? idx + lastindex(t) - 1 : -1)
nothing
end
end

Expand All @@ -405,16 +409,16 @@ Find the previous occurrence of `pattern` in `string` starting at position `star
`pattern` can be either a string, or a regular expression, in which case `string`
must be of type `String`.

The return value is a range of indexes where the matching sequence is found, such that
The return value is a range of indices where the matching sequence is found, such that
`s[findprev(x, s, i)] == x`:

`findprev("substring", string, i)` = `start:end` such that
`string[start:end] == "substring"`, or `0:-1` if unmatched.
`string[start:end] == "substring"`, or `nothing` if unmatched.

# Examples
```jldoctest
julia> findprev("z", "Hello to the world", 18)
0:-1
julia> findprev("z", "Hello to the world", 18) === nothing
true

julia> findprev("o", "Hello to the world", 18)
15:15
Expand Down
4 changes: 2 additions & 2 deletions stdlib/REPL/src/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ function history_search(hist::REPLHistoryProvider, query_buffer::IOBuffer, respo
# First the current response buffer
if 1 <= searchstart <= lastindex(response_str)
match = searchfunc2(searchdata, response_str, searchstart)
if match != 0:-1
if match !== nothing
seek(response_buffer, first(match) - 1)
return true
end
Expand All @@ -642,7 +642,7 @@ function history_search(hist::REPLHistoryProvider, query_buffer::IOBuffer, respo
for idx in idxs
h = hist.history[idx]
match = searchfunc1(searchdata, h)
if match != 0:-1 && h != response_str && haskey(hist.mode_mapping, hist.modes[idx])
if match !== nothing && h != response_str && haskey(hist.mode_mapping, hist.modes[idx])
truncate(response_buffer, 0)
write(response_buffer, h)
seek(response_buffer, first(match) - 1)
Expand Down
2 changes: 1 addition & 1 deletion stdlib/REPL/src/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ function afterusing(string::String, startpos::Int)
isempty(str) && return false
rstr = reverse(str)
r = findfirst(r"\s(gnisu|tropmi)\b", rstr)
isempty(r) && return false
r === nothing && return false
fr = reverseind(str, last(r))
return contains(str[fr:end], r"^\b(using|import)\s*((\w+[.])*\w+\s*,\s*)*$")
end
Expand Down
2 changes: 1 addition & 1 deletion stdlib/REPL/src/docview.jl
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ doc_completions(name::Symbol) = doc_completions(string(name))
# Searching and apropos

# Docsearch simply returns true or false if an object contains the given needle
docsearch(haystack::AbstractString, needle) = !isempty(findfirst(needle, haystack))
docsearch(haystack::AbstractString, needle) = findfirst(needle, haystack) !== nothing
docsearch(haystack::Symbol, needle) = docsearch(string(haystack), needle)
docsearch(::Nothing, needle) = false
function docsearch(haystack::Array, needle)
Expand Down
4 changes: 2 additions & 2 deletions stdlib/REPL/test/repl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ fake_repl() do stdin_write, stdout_read, repl
# Issue #10222
# Test ignoring insert key in standard and prefix search modes
write(stdin_write, "\e[2h\e[2h\n") # insert (VT100-style)
@test findfirst("[2h", readline(stdout_read)) == 0:-1
@test findfirst("[2h", readline(stdout_read)) === nothing
readline(stdout_read)
write(stdin_write, "\e[2~\e[2~\n") # insert (VT220-style)
@test findfirst("[2~", readline(stdout_read)) == 0:-1
@test findfirst("[2~", readline(stdout_read)) === nothing
readline(stdout_read)
write(stdin_write, "1+1\n") # populate history with a trivial input
readline(stdout_read)
Expand Down
Loading