2013-07-30 28 views
8

Có thể kiểm tra xem cụm từ thông dụng nhất định có khớp với bất kỳ chuỗi nào không? Cụ thể, tôi đang tìm hàm matchesEverything($regex) trả về true iff $regex sẽ khớp với bất kỳ chuỗi nào.Kiểm tra xem một regex nhất định có khớp với bất kỳ thứ gì

Tôi cho rằng điều này tương đương với yêu cầu, "được cung cấp một regex r, không tồn tại một chuỗi không khớp với r?" và tôi không nghĩ rằng đây là giải pháp mà không đặt giới hạn trên tập hợp của "tất cả các chuỗi". Tức là, nếu tôi cho rằng các chuỗi sẽ không bao giờ chứa "blahblah", thì tôi có thể chỉ cần kiểm tra xem r có khớp với "blahblah" hay không. Nhưng nếu không có giới hạn như vậy thì sao? Tôi tự hỏi nếu vấn đề này có thể được giải quyết kiểm tra nếu regex r là tương đương với .*.

+4

Tôi tin rằng điều này tương đương với [Sự cố tạm dừng] (http://en.wikipedia.org/wiki/Halting_problem). Không thể viết một thuật toán để xác định xem một regex tùy ý có tương đương với '. *' –

+0

Regexes với các thuật toán và backrefs, nhưng không có nội suy mã, phải là một tập hợp con hoặc bằng ngữ pháp nhạy cảm ngữ cảnh. Quyết định các ngôn ngữ này không hoàn toàn Turing, do đó câu hỏi này không nên tương đương với vấn đề dừng. * Nếu *, cho một CSG, chúng ta có thể tạo ra một chuỗi ngôn ngữ này bằng cách thay thế các quy tắc, sau đó chúng ta có thể áp dụng một sự thay thế bị cấm, do đó tạo ra một chuỗi không có trong ngôn ngữ của chúng ta. Đáng buồn là tôi không biết liệu đây có phải là trường hợp không, và tôi sẽ không thể phác họa bằng chứng về điều này. – amon

+2

Điều này được gọi là "Vấn đề trống rỗng", và có thể giải quyết được cho DFA/NFA (tức là các regex không có phản hồi/giải đáp) http://www.cs.miami.edu/~ogihara/csc527/new04-1.pdf Đối với regexes với backrefs (ngữ pháp nhạy cảm ngữ pháp), vấn đề trống rỗng là undecidable.(Tôi không thể tìm thấy một bằng chứng ngay bây giờ, nhưng nó thường được đề cập trong văn học) – rmmh

Trả lời

12

này không chính xác trả lời câu hỏi của bạn, nhưng hy vọng giải thích một chút lý do tại sao một câu trả lời đơn giản là khó khăn để đi qua:

Trước hết, thuật ngữ 'regex' là một chút âm u, vì vậy chỉ cần làm rõ, chúng tôi có:

  • Cụm từ thông dụng "Nghiêm ngặt", tương đương với các automatons hữu hạn xác định (DFA).
  • Cụm từ thông dụng tương thích Perl (PCRE), bổ sung một loạt các chuông và còi như lookaheads, backreferences, vv Chúng cũng được triển khai bằng các ngôn ngữ khác, chẳng hạn như Python và Java.
  • Biểu thức chính quy Perl thực tế, có thể trở nên điên rồ hơn, bao gồm cả mã Perl tùy ý, thông qua cấu trúc ?{...}.

Tôi nghĩ rằng sự cố này có thể giải quyết được cho các biểu thức chính quy nghiêm ngặt. Bạn chỉ cần xây dựng DFA tương ứng và tìm kiếm biểu đồ đó để xem liệu có bất kỳ đường dẫn nào đến trạng thái không chấp nhận hay không. Nhưng điều đó không giúp cho regex 'thế giới thực', thường là PCRE.

Tôi không nghĩ PCRE là Turing-complete (mặc dù tôi không biết - xem câu hỏi này, quá: Are Perl regexes turing complete?). Nếu đúng như vậy, tôi nghĩ khi Jim Garrison nhận xét, đây là vấn đề cơ bản. Điều đó nói rằng, không dễ dàng chuyển đổi chúng thành một DFA, hoặc là làm cho phương pháp trên vô dụng ...

Tôi không có câu trả lời cho PCRE, nhưng lưu ý rằng các cấu trúc nói trên (backreferences, v.v.) sẽ làm cho nó khá khó khăn, tôi tưởng tượng. Mặc dù tôi ngần ngại nói "không thể."

Một regex Perl chính hãng với ?{...} trong đó chắc chắn là Turing-hoàn chỉnh, do đó, có con rồng, và tôi nghĩ rằng bạn đang ra khỏi may mắn.

+0

trả lời tuyệt vời. bạn đã củng cố những gì tôi đang nghĩ. cho các trường hợp sử dụng mà tôi đang giải quyết, bất kỳ biểu thức chính quy perl thực tế sẽ là những gì tôi quan tâm. khá nhiều thứ mà 'eval {'xx' = ~ m/$ regex/i; } 'kết quả trong một eval thành công. –

Các vấn đề liên quan