2

我正在尝试做一个非常简单的程序来使用 Julia 中的 ismatch() 函数查找匹配项。假设我的模式是

e_pat = r".+@.+"

然后我用一些随机元素制作了一个名为 input 的列表:

input= ["pipo@gmail.com", 23, "trapo", "holi@gmail.com"]

现在我想确定存在多少匹配项,然后使用 e_pat 作为参考打印它们:

for i in input
    println(ismatch(e_pat, i)) && println(i)
end

使用该代码,我只会得到“true”,并且错误显示如下:

true

TypeError: non-boolean (Void) used in boolean context

Stacktrace:
 [1] macro expansion at ./In[27]:4 [inlined]
 [2] anonymous at ./<missing>:?
 [3] include_string(::String, ::String) at ./loading.jl:522

我该怎么做才能获得以下内容?

"pipo@gmail.com"
"holi@gmail.com"

我阅读了 ismatch() 文档,但没有发现任何有用的信息。任何帮助都感激不尽

4

1 回答 1

3

问题是,虽然这个表达式返回 true

julia> @show ismatch(e_pat, "pipo@gmail.com");
ismatch(e_pat,"pipo@gmail.com") = true

使用println, 只打印true返回 nothing

julia> @show println(ismatch(e_pat, "pipo@gmail.com"));
true
println(ismatch(e_pat,"pipo@gmail.com")) = nothing

这是类型Void

julia> typeof(nothing)
Void

错误告诉你不能Void布尔上下文中使用类型对象 ( nothing) 只是Julia中像单例Void一样对待的一个实例:

julia> nothing && true
ERROR: TypeError: non-boolean (Void) used in boolean context

修复后还要注意这也是另一个错误:

julia> @show ismatch(e_pat, 42);
ERROR: MethodError: no method matching ismatch(::Regex, ::Int32)
Closest candidates are:
  ismatch(::Regex, ::SubString{T<:AbstractString}) at regex.jl:151
  ismatch(::Regex, ::SubString{T<:AbstractString}, ::Integer) at regex.jl:151
  ismatch(::Regex, ::AbstractString) at regex.jl:145
  ...

这告诉你ismatch没有这样的方法,你不能将它与类型参数的组合一起使用:(Regex, Int)

你可以做这样的事情来确保所有的对象都是Strings:

julia> input = string.(["pipo@gmail.com", 23, "trapo", "holi@gmail.com"])
4-element Array{String,1}:
 "pipo@gmail.com"
 "23"            
 "trapo"         
 "holi@gmail.com"

最后,您可以使用宏@show(打印表达式及其结果并最终返回结果)而不是println函数(打印结果并返回 nothing)来调试正在发生的事情:

julia> for i in input
           @show(ismatch(e_pat, i)) && println(i)
       end
ismatch(e_pat,i) = true
pipo@gmail.com
ismatch(e_pat,i) = false
ismatch(e_pat,i) = false
ismatch(e_pat,i) = true
holi@gmail.com

因此,为了打印您的预期结果,只需删除左侧println

julia> for i in input
           ismatch(e_pat, i) && println(i)
       end
pipo@gmail.com
holi@gmail.com

如果您想存储它们而不是打印它们,您可以使用数组推导来代替:

julia> result = [str for str in input if ismatch(e_pat, str)]
2-element Array{String,1}:
 "pipo@gmail.com"
 "holi@gmail.com"

或者像这样的索引表达式:

julia> ismatch.(e_pat, input)       
4-element BitArray{1}:              
  true                              
 false                              
 false                              
  true                              

julia> result = input[ismatch.(e_pat, input)]
2-element Array{String,1}:          
 "pipo@gmail.com"                   
 "holi@gmail.com" 

这样您就可以稍后打印它们而无需重复计算:

julia> println.(result)
pipo@gmail.com
holi@gmail.com
于 2018-02-10T04:03:26.787 回答