Skip to content

Commit 33fdd32

Browse files
authored
Merge pull request #26283 from JuliaLang/aa/isfound
Deprecate contains to occursin, deprecate callable regexes
2 parents b4af81d + e238f79 commit 33fdd32

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+486
-486
lines changed

DISTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ for result in eachrow(results)
364364
b = result[:backport]
365365
if (isna(a) && !isna(b)) || (isna(b) && !isna(a))
366366
color = :yellow
367-
elseif a != b && contains(b, "pass")
367+
elseif a != b && occursin("pass", b)
368368
color = :green
369369
elseif a != b
370370
color = :red

NEWS.md

+5
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,11 @@ Deprecated or removed
10791079
* The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree`
10801080
has been renamed to `force` ([#25979]).
10811081

1082+
* `contains` has been deprecated in favor of a more general `occursin` function, which
1083+
takes its arguments in reverse order from `contains` ([#26283]).
1084+
1085+
* `Regex` objects are no longer callable. Use `occursin` instead ([#26283]).
1086+
10821087
* The methods of `range` based on positional arguments have been deprecated in favor of
10831088
keyword arguments ([#25896]).
10841089

base/client.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,11 @@ incomplete_tag(ex) = :none
244244
function incomplete_tag(ex::Expr)
245245
Meta.isexpr(ex, :incomplete) || return :none
246246
msg = ex.args[1]
247-
contains(msg, "string") && return :string
248-
contains(msg, "comment") && return :comment
249-
contains(msg, "requires end") && return :block
250-
contains(msg, "\"`\"") && return :cmd
251-
contains(msg, "character") && return :char
247+
occursin("string", msg) && return :string
248+
occursin("comment", msg) && return :comment
249+
occursin("requires end", msg) && return :block
250+
occursin("\"`\"", msg) && return :cmd
251+
occursin("character", msg) && return :char
252252
return :other
253253
end
254254

base/deprecated.jl

+9-1
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ end
12401240
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
12411241
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)
12421242

1243-
@deprecate ismatch(r::Regex, s::AbstractString) contains(s, r)
1243+
@deprecate ismatch(r::Regex, s::AbstractString) occursin(r, s)
12441244

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

@@ -1467,6 +1467,14 @@ function slicedim(A::AbstractVector, d::Integer, i::Number)
14671467
end
14681468
end
14691469

1470+
# PR #26283
1471+
@deprecate contains(haystack, needle) occursin(needle, haystack)
1472+
@deprecate contains(s::AbstractString, r::Regex, offset::Integer) occursin(r, s, offset=offset)
1473+
function (r::Regex)(s)
1474+
depwarn("`(r::Regex)(s)` is deprecated, use `occursin(r, s)` instead.", :Regex)
1475+
occursin(r, s)
1476+
end
1477+
14701478
# Issue #25786
14711479
@deprecate_binding DevNull devnull
14721480
# TODO: When these are removed, also remove the uppercase variants in libuv.jl and stream.jl

base/exports.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,6 @@ export
446446
zeros,
447447

448448
# search, find, match and related functions
449-
contains,
450449
eachmatch,
451450
endswith,
452451
findall,
@@ -459,6 +458,7 @@ export
459458
findnext,
460459
findprev,
461460
match,
461+
occursin,
462462
searchsorted,
463463
searchsortedfirst,
464464
searchsortedlast,

base/libc.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ function strptime(fmt::AbstractString, timestr::AbstractString)
203203
@static if Sys.isapple()
204204
# if we didn't explicitly parse the weekday or year day, use mktime
205205
# to fill them in automatically.
206-
if !contains(fmt, r"([^%]|^)%(a|A|j|w|Ow)")
206+
if !occursin(r"([^%]|^)%(a|A|j|w|Ow)", fmt)
207207
ccall(:mktime, Int, (Ref{TmStruct},), tm)
208208
end
209209
end

base/loading.jl

+9-9
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ function project_file_name_uuid_path(project_file::String,
388388
uuid = dummy_uuid(project_file)
389389
path = joinpath("src", "$name.jl")
390390
for line in eachline(io)
391-
contains(line, re_section) && break
391+
occursin(re_section, line) && break
392392
if (m = match(re_name_to_string, line)) != nothing
393393
name = String(m.captures[1])
394394
elseif (m = match(re_uuid_to_string, line)) != nothing
@@ -407,7 +407,7 @@ function project_file_manifest_path(project_file::String)::Union{Nothing,String}
407407
open(project_file) do io
408408
dir = abspath(dirname(project_file))
409409
for line in eachline(io)
410-
contains(line, re_section) && break
410+
occursin(re_section, line) && break
411411
if (m = match(re_manifest_to_string, line)) != nothing
412412
return normpath(joinpath(dir, m.captures[1]))
413413
end
@@ -494,9 +494,9 @@ function explicit_project_deps_get(project_file::String, name::String)::Union{Bo
494494
state = :top
495495
for line in eachline(io)
496496
if state == :top
497-
if contains(line, re_section)
497+
if occursin(re_section, line)
498498
root_name == name && return root_uuid
499-
state = contains(line, re_section_deps) ? :deps : :other
499+
state = occursin(re_section_deps, line) ? :deps : :other
500500
elseif (m = match(re_name_to_string, line)) != nothing
501501
root_name = String(m.captures[1])
502502
elseif (m = match(re_uuid_to_string, line)) != nothing
@@ -506,7 +506,7 @@ function explicit_project_deps_get(project_file::String, name::String)::Union{Bo
506506
if (m = match(re_key_to_string, line)) != nothing
507507
m.captures[1] == name && return UUID(m.captures[2])
508508
end
509-
elseif contains(line, re_section)
509+
elseif occursin(re_section, line)
510510
state = :deps
511511
end
512512
end
@@ -524,7 +524,7 @@ function explicit_manifest_deps_get(manifest_file::String, where::UUID, name::St
524524
uuid = deps = nothing
525525
state = :other
526526
for line in eachline(io)
527-
if contains(line, re_array_of_tables)
527+
if occursin(re_array_of_tables, line)
528528
uuid == where && break
529529
uuid = deps = nothing
530530
state = :stanza
@@ -533,9 +533,9 @@ function explicit_manifest_deps_get(manifest_file::String, where::UUID, name::St
533533
uuid = UUID(m.captures[1])
534534
elseif (m = match(re_deps_to_any, line)) != nothing
535535
deps = String(m.captures[1])
536-
elseif contains(line, re_subsection_deps)
536+
elseif occursin(re_subsection_deps, line)
537537
state = :deps
538-
elseif contains(line, re_section)
538+
elseif occursin(re_section, line)
539539
state = :other
540540
end
541541
elseif state == :deps && uuid == where
@@ -551,7 +551,7 @@ function explicit_manifest_deps_get(manifest_file::String, where::UUID, name::St
551551
@warn "Unexpected TOML deps format:\n$deps"
552552
return nothing
553553
end
554-
contains(deps, repr(name)) || return true
554+
occursin(repr(name), deps) || return true
555555
seekstart(io) # rewind IO handle
556556
manifest_file_name_uuid(manifest_file, name, io)
557557
end

base/methodshow.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ function url(m::Method)
202202
(m.file == :null || m.file == :string) && return ""
203203
file = string(m.file)
204204
line = m.line
205-
line <= 0 || contains(file, r"In\[[0-9]+\]") && return ""
205+
line <= 0 || occursin(r"In\[[0-9]+\]", file) && return ""
206206
Sys.iswindows() && (file = replace(file, '\\' => '/'))
207207
libgit2_id = PkgId(UUID((0x76f85450_5226_5b5a,0x8eaa_529ad045b433)), "LibGit2")
208208
if inbase(M)

base/mpfr.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ end
936936

937937
function _prettify_bigfloat(s::String)::String
938938
mantissa, exponent = split(s, 'e')
939-
if !contains(mantissa, '.')
939+
if !occursin('.', mantissa)
940940
mantissa = string(mantissa, '.')
941941
end
942942
mantissa = rstrip(mantissa, '0')

base/path.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ end
7878

7979

8080
if Sys.iswindows()
81-
isabspath(path::String) = contains(path, path_absolute_re)
81+
isabspath(path::String) = occursin(path_absolute_re, path)
8282
else
8383
isabspath(path::String) = startswith(path, '/')
8484
end
@@ -113,7 +113,7 @@ julia> isdirpath("/home/")
113113
true
114114
```
115115
"""
116-
isdirpath(path::String) = contains(splitdrive(path)[2], path_directory_re)
116+
isdirpath(path::String) = occursin(path_directory_re, splitdrive(path)[2])
117117

118118
"""
119119
splitdir(path::AbstractString) -> (AbstractString, AbstractString)
@@ -219,7 +219,7 @@ function joinpath(a::String, b::String)
219219
!isempty(B) && A != B && return string(B,b)
220220
C = isempty(B) ? A : B
221221
isempty(a) ? string(C,b) :
222-
contains(a[end:end], path_separator_re) ? string(C,a,b) :
222+
occursin(path_separator_re, a[end:end]) ? string(C,a,b) :
223223
string(C,a,pathsep(a,b),b)
224224
end
225225
joinpath(a::AbstractString, b::AbstractString) = joinpath(String(a), String(b))

base/regex.jl

+2-4
Original file line numberDiff line numberDiff line change
@@ -141,20 +141,18 @@ function getindex(m::RegexMatch, name::Symbol)
141141
end
142142
getindex(m::RegexMatch, name::AbstractString) = m[Symbol(name)]
143143

144-
function contains(s::AbstractString, r::Regex, offset::Integer=0)
144+
function occursin(r::Regex, s::AbstractString; offset::Integer=0)
145145
compile(r)
146146
return PCRE.exec(r.regex, String(s), offset, r.match_options,
147147
r.match_data)
148148
end
149149

150-
function contains(s::SubString, r::Regex, offset::Integer=0)
150+
function occursin(r::Regex, s::SubString; offset::Integer=0)
151151
compile(r)
152152
return PCRE.exec(r.regex, s, offset, r.match_options,
153153
r.match_data)
154154
end
155155

156-
(r::Regex)(s) = contains(s, r)
157-
158156
"""
159157
match(r::Regex, s::AbstractString[, idx::Integer[, addopts]])
160158

base/strings/search.jl

+7-9
Original file line numberDiff line numberDiff line change
@@ -433,29 +433,27 @@ julia> findprev("Julia", "JuliaLang", 6)
433433
findprev(t::AbstractString, s::AbstractString, i::Integer) = _rsearch(s, t, i)
434434

435435
"""
436-
contains(haystack::AbstractString, needle::Union{AbstractString,Regex,AbstractChar})
436+
occursin(needle::Union{AbstractString,Regex,AbstractChar}, haystack::AbstractString)
437437
438438
Determine whether the second argument is a substring of the first. If `needle`
439439
is a regular expression, checks whether `haystack` contains a match.
440440
441441
# Examples
442442
```jldoctest
443-
julia> contains("JuliaLang is pretty cool!", "Julia")
443+
julia> occursin("Julia", "JuliaLang is pretty cool!")
444444
true
445445
446-
julia> contains("JuliaLang is pretty cool!", 'a')
446+
julia> occursin('a', "JuliaLang is pretty cool!")
447447
true
448448
449-
julia> contains("aba", r"a.a")
449+
julia> occursin(r"a.a", "aba")
450450
true
451451
452-
julia> contains("abba", r"a.a")
452+
julia> occursin(r"a.a", "abba")
453453
false
454454
```
455455
"""
456-
function contains end
457-
458-
contains(haystack::AbstractString, needle::Union{AbstractString,AbstractChar}) =
456+
occursin(needle::Union{AbstractString,AbstractChar}, haystack::AbstractString) =
459457
_searchindex(haystack, needle, firstindex(haystack)) != 0
460458

461-
in(::AbstractString, ::AbstractString) = error("use contains(x,y) for string containment")
459+
in(::AbstractString, ::AbstractString) = error("use occursin(x, y) for string containment")

base/uuid.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ let groupings = [1:8; 10:13; 15:18; 20:23; 25:36]
3030
function UUID(s::AbstractString)
3131
s = lowercase(s)
3232

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

base/version.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct VersionNumber
2121
if ident isa Integer
2222
ident >= 0 || throw(ArgumentError("invalid negative pre-release identifier: $ident"))
2323
else
24-
if !contains(ident, r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i) ||
24+
if !occursin(r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i, ident) ||
2525
isempty(ident) && !(length(pre)==1 && isempty(bld))
2626
throw(ArgumentError("invalid pre-release identifier: $(repr(ident))"))
2727
end
@@ -31,7 +31,7 @@ struct VersionNumber
3131
if ident isa Integer
3232
ident >= 0 || throw(ArgumentError("invalid negative build identifier: $ident"))
3333
else
34-
if !contains(ident, r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i) ||
34+
if !occursin(r"^(?:|[0-9a-z-]*[a-z-][0-9a-z-]*)$"i, ident) ||
3535
isempty(ident) && length(bld)!=1
3636
throw(ArgumentError("invalid build identifier: $(repr(ident))"))
3737
end
@@ -83,7 +83,7 @@ function split_idents(s::AbstractString)
8383
idents = split(s, '.')
8484
ntuple(length(idents)) do i
8585
ident = idents[i]
86-
contains(ident, r"^\d+$") ? parse(UInt64, ident) : String(ident)
86+
occursin(r"^\d+$", ident) ? parse(UInt64, ident) : String(ident)
8787
end
8888
end
8989

contrib/add_license_to_files.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function check_lines!(
8181
remove = []
8282
for i in 1:length(lines)
8383
line = lines[i]
84-
if contains(line, checktxt)
84+
if occursin(checktxt, line)
8585
if strip(line) == strip(prefix * checktxt) || strip(line) == strip(checktxt)
8686
push!(remove, i)
8787
else

contrib/fixup_precompile.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
function needs_USE_GPL_LIBS(s::String)
2-
contains(s, "CHOLMOD") && return true
2+
occursin("CHOLMOD", s) && return true
33
return false
44
end
55

@@ -24,7 +24,7 @@ function fixup_precompile(new_precompile_file; merge=false)
2424
for line in eachline(file)
2525
line = strip(line)
2626
# filter out closures, which might have different generated names in different environments
27-
contains(line, r"#[0-9]") && continue
27+
occursin(r"#[0-9]", line) && continue
2828
# Other stuff than precompile statements might have been written to STDERR
2929
startswith(line, "precompile(Tuple{") || continue
3030
# Ok, add the line
@@ -65,4 +65,4 @@ elseif length(ARGS) == 2
6565
fixup_precompile(joinpath(pwd(), ARGS[2]); merge = true)
6666
else
6767
error("invalid arguments")
68-
end
68+
end

doc/src/base/strings.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Base.findfirst(::AbstractString, ::AbstractString)
3838
Base.findnext(::AbstractString, ::AbstractString, ::Integer)
3939
Base.findlast(::AbstractString, ::AbstractString)
4040
Base.findprev(::AbstractString, ::AbstractString, ::Integer)
41-
Base.contains
41+
Base.occursin
4242
Base.reverse(::Union{String,SubString{String}})
4343
Base.replace(s::AbstractString, ::Pair)
4444
Base.split

doc/src/manual/strings.md

+13-13
Original file line numberDiff line numberDiff line change
@@ -537,23 +537,23 @@ julia> findnext(isequal('o'), "xylophone", 5)
537537
julia> findnext(isequal('o'), "xylophone", 8)
538538
```
539539

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

542542
```jldoctest
543-
julia> contains("Hello, world.", "world")
543+
julia> occursin("world", "Hello, world.")
544544
true
545545
546-
julia> contains("Xylophon", "o")
546+
julia> occursin("o", "Xylophon")
547547
true
548548
549-
julia> contains("Xylophon", "a")
549+
julia> occursin("a", "Xylophon")
550550
false
551551
552-
julia> contains("Xylophon", 'o')
552+
julia> occursin('o', "Xylophon")
553553
true
554554
```
555555

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

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

@@ -608,20 +608,20 @@ julia> typeof(ans)
608608
Regex
609609
```
610610

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

613613
```jldoctest
614-
julia> contains("not a comment", r"^\s*(?:#|$)")
614+
julia> occursin(r"^\s*(?:#|$)", "not a comment")
615615
false
616616
617-
julia> contains("# a comment", r"^\s*(?:#|$)")
617+
julia> occursin(r"^\s*(?:#|$)", "# a comment")
618618
true
619619
```
620620

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

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

0 commit comments

Comments
 (0)