相关问题:
这个问题相当简单。我发现其他语言有很多替代方法,但是在Julia中没有:
此外,Random.randstring
不接受Regex
作为参数。
相关问题:
这个问题相当简单。我发现其他语言有很多替代方法,但是在Julia中没有:
此外,Random.randstring
不接受Regex
作为参数。
可以使用 Automa.jl构建DFA并随机遍历它。Automa使用比PCRE更简单的语法,因此您可以用它描述的语言实际上应该是正则的。
我快速地根据dot.jl
中的代码编写了以下内容:
julia> function rand_re(machine::Automa.Machine)
out = IOBuffer()
node = machine.start
while true
if node.state ∈ machine.final_states
(rand() ≤ 1 / (length(node.edges) + 1)) && break
end
edge, node = rand(node.edges)
label = rand(collect(edge.labels))
print(out, Char(label))
end
return String(take!(out))
end
rand_re (generic function with 1 method)
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a6bbb"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a9b"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a3aa"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a1a"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a5ba"
Char(label)
的地方需要更加小心。ccall
或 PyCall
调用 rxvm_gen
或 Rxvm.gen
of librxvm
,其中包含(可能)非回溯正则表达式的性能良好的代码。Julia有PCRE,这意味着它的正则表达式比真正的正则表达式更强大。实际上,它们是图灵完备的。 我怀疑这方面有很多有趣的理论计算机科学问题。 因为停机问题的原因,我认为PCRE的任务可能是不可能完成的。 但我们仍然可以尝试一堆随机字符串并丢弃那些不匹配的字符串。对于简单的正则表达式,这样做已经足够了。 当然,并不能保证能给出答案。
如果需要更严格的正则表达式,例如Automa.jl所涵盖的正则表达式,则可能有更好的方法,因为你可以逐位解决状态机。 希望熟悉Automa.jl的人可以发布自己的答案。
using Random: randstring
function rand_matching(regex; max_len=2^16, max_attempts=1000)
for _ in max_attempts
str = randstring(max_len)
m = match(regex, str)
if m != nothing
# rather than return whole string,
# just return the shortest bit that matches
return m.match
end
end
error("Could not find any string that matches regex")
end
julia> @time rand_matching(r"\d\d")
0.013517 seconds (34.34 k allocations: 1.998 MiB)
"38"
julia> @time rand_matching(r"\d\d")
0.001497 seconds (11 allocations: 128.656 KiB)
"44"
julia> @time rand_matching(r"a\d\d")
0.000670 seconds (11 allocations: 128.656 KiB)
"a19"
julia> @time rand_matching(r"a\d\d")
0.000775 seconds (11 allocations: 128.656 KiB)
"a83"
julia> @time rand_matching(r"a\d\db")
0.000670 seconds (11 allocations: 128.656 KiB)
"a44b"