Contains vs occursin

Is there any functional difference between contains and occursin? Is it up to preference?

It looks like occursin additionally supports IOBuffer haystacks in addition to AbstractString (as well as an undocumented offset kwarg with regexes), but otherwise the two are identical. In fact, contains is defined by occursin:

julia> methods(occursin)
# 5 methods for generic function "occursin" from Base:
 [1] occursin(r::Regex, s::SubString{String}; offset)
     @ regex.jl:311
 [2] occursin(haystack)
     @ strings/search.jl:885
 [3] occursin(r::Regex, s::AbstractString; offset)
     @ regex.jl:306
 [4] occursin(needle::Union{AbstractChar, AbstractString}, haystack::AbstractString)
     @ strings/search.jl:860
 [5] occursin(delim::UInt8, buf::Base.GenericIOBuffer)
     @ iobuffer.jl:977

julia> methods(contains)
# 2 methods for generic function "contains" from Base:
 [1] contains(needle)
     @ strings/util.jl:197
 [2] contains(haystack::AbstractString, needle)
     @ strings/util.jl:140

julia> less(contains, (AbstractString,Any))
contains(haystack::AbstractString, needle) = occursin(needle, haystack)
2 Likes

A difference related to the different order of the arguments is that contains(x) can be used to quickly filter an iterable, for example

julia> filter(contains("hello"), ["hello world", "foo bar"])
1-element Vector{String}:
 "hello world"

but

julia> filter(occursin("hello"), ["hello world", "foo bar"])
String[]

It’s not that they’re functionally different, but the order of the arguments matter for the one-argument methods.

4 Likes