Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate contains to occursin, deprecate callable regexes #26283

Merged
merged 2 commits into from
Mar 20, 2018
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
2 changes: 1 addition & 1 deletion DISTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ for result in eachrow(results)
b = result[:backport]
if (isna(a) && !isna(b)) || (isna(b) && !isna(a))
color = :yellow
elseif a != b && contains(b, "pass")
elseif a != b && occursin("pass", b)
color = :green
elseif a != b
color = :red
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,11 @@ Deprecated or removed
* The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree`
has been renamed to `force` ([#25979]).

* `contains` has been deprecated in favor of a more general `occursin` function, which
takes its arguments in reverse order from `contains` ([#26283]).

* `Regex` objects are no longer callable. Use `occursin` instead ([#26283]).

* The methods of `range` based on positional arguments have been deprecated in favor of
keyword arguments ([#25896]).

Expand Down
10 changes: 5 additions & 5 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,11 @@ incomplete_tag(ex) = :none
function incomplete_tag(ex::Expr)
Meta.isexpr(ex, :incomplete) || return :none
msg = ex.args[1]
contains(msg, "string") && return :string
contains(msg, "comment") && return :comment
contains(msg, "requires end") && return :block
contains(msg, "\"`\"") && return :cmd
contains(msg, "character") && return :char
occursin("string", msg) && return :string
occursin("comment", msg) && return :comment
occursin("requires end", msg) && return :block
occursin("\"`\"", msg) && return :cmd
occursin("character", msg) && return :char
return :other
end

Expand Down
10 changes: 9 additions & 1 deletion base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ end
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)

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

@deprecate findin(a, b) findall(in(b), a)

Expand Down Expand Up @@ -1467,6 +1467,14 @@ function slicedim(A::AbstractVector, d::Integer, i::Number)
end
end

# PR #26283
@deprecate contains(haystack, needle) occursin(needle, haystack)
@deprecate contains(s::AbstractString, r::Regex, offset::Integer) occursin(r, s, offset=offset)
function (r::Regex)(s)
depwarn("`(r::Regex)(s)` is deprecated, use `occursin(r, s)` instead.", :Regex)
occursin(r, s)
end

# Issue #25786
@deprecate_binding DevNull devnull
# TODO: When these are removed, also remove the uppercase variants in libuv.jl and stream.jl
Expand Down
2 changes: 1 addition & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,6 @@ export
zeros,

# search, find, match and related functions
contains,
eachmatch,
endswith,
findall,
Expand All @@ -459,6 +458,7 @@ export
findnext,
findprev,
match,
occursin,
searchsorted,
searchsortedfirst,
searchsortedlast,
Expand Down
2 changes: 1 addition & 1 deletion base/libc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function strptime(fmt::AbstractString, timestr::AbstractString)
@static if Sys.isapple()
# if we didn't explicitly parse the weekday or year day, use mktime
# to fill them in automatically.
if !contains(fmt, r"([^%]|^)%(a|A|j|w|Ow)")
if !occursin(r"([^%]|^)%(a|A|j|w|Ow)", fmt)
ccall(:mktime, Int, (Ref{TmStruct},), tm)
end
end
Expand Down
18 changes: 9 additions & 9 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ function project_file_name_uuid_path(project_file::String,
uuid = dummy_uuid(project_file)
path = joinpath("src", "$name.jl")
for line in eachline(io)
contains(line, re_section) && break
occursin(re_section, line) && break
if (m = match(re_name_to_string, line)) != nothing
name = String(m.captures[1])
elseif (m = match(re_uuid_to_string, line)) != nothing
Expand All @@ -407,7 +407,7 @@ function project_file_manifest_path(project_file::String)::Union{Nothing,String}
open(project_file) do io
dir = abspath(dirname(project_file))
for line in eachline(io)
contains(line, re_section) && break
occursin(re_section, line) && break
if (m = match(re_manifest_to_string, line)) != nothing
return normpath(joinpath(dir, m.captures[1]))
end
Expand Down Expand Up @@ -494,9 +494,9 @@ function explicit_project_deps_get(project_file::String, name::String)::Union{Bo
state = :top
for line in eachline(io)
if state == :top
if contains(line, re_section)
if occursin(re_section, line)
root_name == name && return root_uuid
state = contains(line, re_section_deps) ? :deps : :other
state = occursin(re_section_deps, line) ? :deps : :other
elseif (m = match(re_name_to_string, line)) != nothing
root_name = String(m.captures[1])
elseif (m = match(re_uuid_to_string, line)) != nothing
Expand All @@ -506,7 +506,7 @@ function explicit_project_deps_get(project_file::String, name::String)::Union{Bo
if (m = match(re_key_to_string, line)) != nothing
m.captures[1] == name && return UUID(m.captures[2])
end
elseif contains(line, re_section)
elseif occursin(re_section, line)
state = :deps
end
end
Expand All @@ -524,7 +524,7 @@ function explicit_manifest_deps_get(manifest_file::String, where::UUID, name::St
uuid = deps = nothing
state = :other
for line in eachline(io)
if contains(line, re_array_of_tables)
if occursin(re_array_of_tables, line)
uuid == where && break
uuid = deps = nothing
state = :stanza
Expand All @@ -533,9 +533,9 @@ function explicit_manifest_deps_get(manifest_file::String, where::UUID, name::St
uuid = UUID(m.captures[1])
elseif (m = match(re_deps_to_any, line)) != nothing
deps = String(m.captures[1])
elseif contains(line, re_subsection_deps)
elseif occursin(re_subsection_deps, line)
state = :deps
elseif contains(line, re_section)
elseif occursin(re_section, line)
state = :other
end
elseif state == :deps && uuid == where
Expand All @@ -551,7 +551,7 @@ function explicit_manifest_deps_get(manifest_file::String, where::UUID, name::St
@warn "Unexpected TOML deps format:\n$deps"
return nothing
end
contains(deps, repr(name)) || return true
occursin(repr(name), deps) || return true
seekstart(io) # rewind IO handle
manifest_file_name_uuid(manifest_file, name, io)
end
Expand Down
2 changes: 1 addition & 1 deletion base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ function url(m::Method)
(m.file == :null || m.file == :string) && return ""
file = string(m.file)
line = m.line
line <= 0 || contains(file, r"In\[[0-9]+\]") && return ""
line <= 0 || occursin(r"In\[[0-9]+\]", file) && return ""
Sys.iswindows() && (file = replace(file, '\\' => '/'))
libgit2_id = PkgId(UUID((0x76f85450_5226_5b5a,0x8eaa_529ad045b433)), "LibGit2")
if inbase(M)
Expand Down
2 changes: 1 addition & 1 deletion base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ end

function _prettify_bigfloat(s::String)::String
mantissa, exponent = split(s, 'e')
if !contains(mantissa, '.')
if !occursin('.', mantissa)
mantissa = string(mantissa, '.')
end
mantissa = rstrip(mantissa, '0')
Expand Down
6 changes: 3 additions & 3 deletions base/path.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ end


if Sys.iswindows()
isabspath(path::String) = contains(path, path_absolute_re)
isabspath(path::String) = occursin(path_absolute_re, path)
else
isabspath(path::String) = startswith(path, '/')
end
Expand Down Expand Up @@ -113,7 +113,7 @@ julia> isdirpath("/home/")
true
```
"""
isdirpath(path::String) = contains(splitdrive(path)[2], path_directory_re)
isdirpath(path::String) = occursin(path_directory_re, splitdrive(path)[2])

"""
splitdir(path::AbstractString) -> (AbstractString, AbstractString)
Expand Down Expand Up @@ -219,7 +219,7 @@ function joinpath(a::String, b::String)
!isempty(B) && A != B && return string(B,b)
C = isempty(B) ? A : B
isempty(a) ? string(C,b) :
contains(a[end:end], path_separator_re) ? string(C,a,b) :
occursin(path_separator_re, a[end:end]) ? string(C,a,b) :
string(C,a,pathsep(a,b),b)
end
joinpath(a::AbstractString, b::AbstractString) = joinpath(String(a), String(b))
Expand Down
6 changes: 2 additions & 4 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,18 @@ function getindex(m::RegexMatch, name::Symbol)
end
getindex(m::RegexMatch, name::AbstractString) = m[Symbol(name)]

function contains(s::AbstractString, r::Regex, offset::Integer=0)
function occursin(r::Regex, s::AbstractString; offset::Integer=0)
compile(r)
return PCRE.exec(r.regex, String(s), offset, r.match_options,
r.match_data)
end

function contains(s::SubString, r::Regex, offset::Integer=0)
function occursin(r::Regex, s::SubString; offset::Integer=0)
compile(r)
return PCRE.exec(r.regex, s, offset, r.match_options,
r.match_data)
end

(r::Regex)(s) = contains(s, r)

"""
match(r::Regex, s::AbstractString[, idx::Integer[, addopts]])

Expand Down
16 changes: 7 additions & 9 deletions base/strings/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -433,29 +433,27 @@ julia> findprev("Julia", "JuliaLang", 6)
findprev(t::AbstractString, s::AbstractString, i::Integer) = _rsearch(s, t, i)

"""
contains(haystack::AbstractString, needle::Union{AbstractString,Regex,AbstractChar})
occursin(needle::Union{AbstractString,Regex,AbstractChar}, haystack::AbstractString)

Determine whether the second argument is a substring of the first. If `needle`
is a regular expression, checks whether `haystack` contains a match.

# Examples
```jldoctest
julia> contains("JuliaLang is pretty cool!", "Julia")
julia> occursin("Julia", "JuliaLang is pretty cool!")
true

julia> contains("JuliaLang is pretty cool!", 'a')
julia> occursin('a', "JuliaLang is pretty cool!")
true

julia> contains("aba", r"a.a")
julia> occursin(r"a.a", "aba")
true

julia> contains("abba", r"a.a")
julia> occursin(r"a.a", "abba")
false
```
"""
function contains end

contains(haystack::AbstractString, needle::Union{AbstractString,AbstractChar}) =
occursin(needle::Union{AbstractString,AbstractChar}, haystack::AbstractString) =
_searchindex(haystack, needle, firstindex(haystack)) != 0

in(::AbstractString, ::AbstractString) = error("use contains(x,y) for string containment")
in(::AbstractString, ::AbstractString) = error("use occursin(x, y) for string containment")
2 changes: 1 addition & 1 deletion base/uuid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ let groupings = [1:8; 10:13; 15:18; 20:23; 25:36]
function UUID(s::AbstractString)
s = lowercase(s)

if !contains(s, r"^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$")
if !occursin(r"^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$", s)
throw(ArgumentError("Malformed UUID string: $(repr(s))"))
end

Expand Down
6 changes: 3 additions & 3 deletions base/version.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct VersionNumber
if ident isa Integer
ident >= 0 || throw(ArgumentError("invalid negative pre-release identifier: $ident"))
else
if !contains(ident, r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i) ||
if !occursin(r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i, ident) ||
isempty(ident) && !(length(pre)==1 && isempty(bld))
throw(ArgumentError("invalid pre-release identifier: $(repr(ident))"))
end
Expand All @@ -31,7 +31,7 @@ struct VersionNumber
if ident isa Integer
ident >= 0 || throw(ArgumentError("invalid negative build identifier: $ident"))
else
if !contains(ident, r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i) ||
if !occursin(r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i, ident) ||
isempty(ident) && length(bld)!=1
throw(ArgumentError("invalid build identifier: $(repr(ident))"))
end
Expand Down Expand Up @@ -83,7 +83,7 @@ function split_idents(s::AbstractString)
idents = split(s, '.')
ntuple(length(idents)) do i
ident = idents[i]
contains(ident, r"^\d+$") ? parse(UInt64, ident) : String(ident)
occursin(r"^\d+$", ident) ? parse(UInt64, ident) : String(ident)
end
end

Expand Down
2 changes: 1 addition & 1 deletion contrib/add_license_to_files.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function check_lines!(
remove = []
for i in 1:length(lines)
line = lines[i]
if contains(line, checktxt)
if occursin(checktxt, line)
if strip(line) == strip(prefix * checktxt) || strip(line) == strip(checktxt)
push!(remove, i)
else
Expand Down
6 changes: 3 additions & 3 deletions contrib/fixup_precompile.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function needs_USE_GPL_LIBS(s::String)
contains(s, "CHOLMOD") && return true
occursin("CHOLMOD", s) && return true
return false
end

Expand All @@ -24,7 +24,7 @@ function fixup_precompile(new_precompile_file; merge=false)
for line in eachline(file)
line = strip(line)
# filter out closures, which might have different generated names in different environments
contains(line, r"#[0-9]") && continue
occursin(r"#[0-9]", line) && continue
# Other stuff than precompile statements might have been written to STDERR
startswith(line, "precompile(Tuple{") || continue
# Ok, add the line
Expand Down Expand Up @@ -65,4 +65,4 @@ elseif length(ARGS) == 2
fixup_precompile(joinpath(pwd(), ARGS[2]); merge = true)
else
error("invalid arguments")
end
end
2 changes: 1 addition & 1 deletion doc/src/base/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Base.findfirst(::AbstractString, ::AbstractString)
Base.findnext(::AbstractString, ::AbstractString, ::Integer)
Base.findlast(::AbstractString, ::AbstractString)
Base.findprev(::AbstractString, ::AbstractString, ::Integer)
Base.contains
Base.occursin
Base.reverse(::Union{String,SubString{String}})
Base.replace(s::AbstractString, ::Pair)
Base.split
Expand Down
26 changes: 13 additions & 13 deletions doc/src/manual/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,23 +537,23 @@ julia> findnext(isequal('o'), "xylophone", 5)
julia> findnext(isequal('o'), "xylophone", 8)
```

You can use the [`contains`](@ref) function to check if a substring is contained in a string:
You can use the [`occursin`](@ref) function to check if a substring is found within a string:

```jldoctest
julia> contains("Hello, world.", "world")
julia> occursin("world", "Hello, world.")
true

julia> contains("Xylophon", "o")
julia> occursin("o", "Xylophon")
true

julia> contains("Xylophon", "a")
julia> occursin("a", "Xylophon")
false

julia> contains("Xylophon", 'o')
julia> occursin('o', "Xylophon")
true
```

The last example shows that [`contains`](@ref) can also look for a character literal.
The last example shows that [`occursin`](@ref) can also look for a character literal.

Two other handy string functions are [`repeat`](@ref) and [`join`](@ref):

Expand Down Expand Up @@ -608,20 +608,20 @@ julia> typeof(ans)
Regex
```

To check if a regex matches a string, use [`contains`](@ref):
To check if a regex matches a string, use [`occursin`](@ref):

```jldoctest
julia> contains("not a comment", r"^\s*(?:#|$)")
julia> occursin(r"^\s*(?:#|$)", "not a comment")
false

julia> contains("# a comment", r"^\s*(?:#|$)")
julia> occursin(r"^\s*(?:#|$)", "# a comment")
true
```

As one can see here, [`contains`](@ref) simply returns true or false, indicating whether the
given regex matches the string or not. Commonly, however, one wants to know not just whether a
string matched, but also *how* it matched. To capture this information about a match, use the
[`match`](@ref) function instead:
As one can see here, [`occursin`](@ref) simply returns true or false, indicating whether a
match for the given regex occurs in the string. Commonly, however, one wants to know not
just whether a string matched, but also *how* it matched. To capture this information about
a match, use the [`match`](@ref) function instead:

```jldoctest
julia> match(r"^\s*(?:#|$)", "not a comment")
Expand Down
Loading