Làm cách nào để tạo chuỗi ngẫu nhiên phù hợp với Regex trong Julia?


8

Câu hỏi liên quan:

Câu hỏi khá đơn giản. Tôi đã tìm thấy nhiều lựa chọn thay thế cho các ngôn ngữ khác, nhưng không phải ở Julia:

Trình tạo văn bản ngẫu nhiên dựa trên regex

Cũng Random.randstringkhông lấy Regexlàm đối số.

Câu trả lời:


5

Có thể sử dụng Automa.jl để xây dựng DFA và duyệt ngẫu nhiên nó. Automa sử dụng một cú pháp đơn giản hơn PCRE, do đó, ngôn ngữ bạn có thể mô tả bằng nó thực sự nên thường xuyên.

Tôi nhanh chóng tập hợp các mục sau, chủ yếu dựa vào mã trong 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"

Thông báo trước là Automa sử dụng các bộ được mã hóa byte cho các nhãn cạnh, vì vậy cần cẩn thận hơn khi tôi chỉ viết Char(label).

Vì các trạng thái cuối cùng vẫn có thể có các cạnh đi, tôi đã chọn xử lý dừng và mỗi cạnh với xác suất đồng nhất. Tôi nghĩ rằng điều này có thể sẽ có tác động rằng các thuật ngữ có khả năng vô hạn sẽ rất ngắn hoặc rất dài; google "Bộ lấy mẫu Boltzmann" để biết cách giải quyết điều đó (không bị nhầm lẫn với lấy mẫu từ bản phân phối Boltzmann!), nhưng giải pháp này khá liên quan đến toán học.


5

Julia có PCRE , có nghĩa là các biểu thức chính quy của nó mạnh hơn nhiều so với các biểu thức thông thường thực sự. Và trong thực tế turing hoàn thành. Tôi nghi ngờ có một loạt các khoa học máy tính lý thuyết thú vị xung quanh này. Tôi nghi ngờ nhiệm vụ của bạn cho PCRE có thể được chứng minh là không thể vì vấn đề tạm dừng . Nhưng vẫn là những gì chúng ta có thể làm là thử một loạt các chuỗi ngẫu nhiên và loại bỏ những chuỗi không khớp. Và cho regex đơn giản mà đi một chặng đường dài. Nó không được đảm bảo để đưa ra một câu trả lời mặc dù.

Nếu ai đó muốn regex chặt chẽ hơn, như những thứ được bao phủ bởi Automa.jl , có lẽ có một cái gì đó tốt hơn có thể được thực hiện, vì bạn có thể đi bộ máy trạng thái giải quyết nó 1 bit mỗi lần. Hy vọng ai đó biết Automa.jl có thể đăng câu trả lời của riêng họ.

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

bản giới thiệu:

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"

Nhiều triển khai được tìm thấy cho các ngôn ngữ khác (ngay cả những PC triển khai) khiến tôi tin rằng nhiệm vụ này là không thể, tôi đã không đi sâu vào chi tiết, có thể chúng đang sử dụng phiên bản PCRE chặt chẽ hơn. Ném các chuỗi ngẫu nhiên với hy vọng rằng một kết hợp với regex là ổn đối với regex nhỏ, đơn giản nhưng nó không có quy mô rất tốt ... Cảm ơn bạn đã chỉ cho tôi về Automa vì nó khớp chính xác với bước tiếp theo của vấn đề của tôi. Và có lẽ nó có thể giết chết hai con chim bằng một hòn đá!
Thomas Jalabert

Hơn nữa, ngay cả khi nó không phải là không thể (tạm dừng vấn đề tương đương), nó vẫn có độ phức tạp thời gian rất lớn. Bạn có thể thực hiện bất kỳ vấn đề nào dưới dạng biểu thức PCRE chỉ chấp nhận giải pháp. Vì vậy, ví dụ, bạn có thể phá vỡ mã hóa khóa chung, với PCRE chỉ chấp nhận khóa riêng, sau đó yêu cầu mã hóa ngẫu nhiên. Hoặc thực hiện bất kỳ vấn đề NP-Complete nào, như tổng tập hợp con, chấp nhận Thoặc Ftùy thuộc vào việc liệu tổng hợp ngoại lệ. Nếu trình tạo regex phù hợp với PCRE của bạn hoạt động trong thời gian đa thức, thì xin chúc mừng bạn đã chứng minh P = NP.
Lyndon White

Hmm, có lẽ PCRE vẫn chưa hoàn thành. Tôi chỉ có thể sai ở đó. Chúng chỉ có thể là Equivi cho ngữ pháp miễn phí ngữ cảnh. Họ có thể làm một số điều điên rồ, như phát hiện chính. Vì vậy, defs có thể tạo ra các số nguyên tố với trình tạo chuỗi ngẫu nhiên của bạn. Và có lẽ có thể phá vỡ mật mã khóa công khai.
Lyndon White
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.