2011-03-15 14 views
5

Regex bệnh lý nào làm phát sinh nhiều trình phân tích cú pháp (cả trong thời gian & bộ nhớ)? và trình phân tích cú pháp nào? Điểm thưởng cơ bản hơn và chuẩn là regex, và nhiều khả năng người dùng không độc hại có thể ngây thơ đến với nó. Hãy thoải mái đăng dữ liệu thời gian thực và bộ nhớ cũng như phiên bản phân tích cú pháp.Regex bệnh lý có thể phát sinh (thời gian và bộ nhớ)?

(tôi dường như nhớ rằng khẳng định lookbehind quá mức hoặc (EDIT:) backtracking trong PERL được cho là để làm điều này, hoặc ít nhất đã từng là gì nữa.?)

+1

Suy nghĩ của bạn về backtracking, hầu như bất kỳ công cụ regex dựa trên NFA nào đều có thể bị lừa vào backtracking bán vô hạn nếu bạn có thể điều khiển cả chủ thể và mẫu. DFA dựa trên động cơ không cần phải làm backtracking, do đó, họ không bị lỗ hổng đó. Câu trả lời cho các câu hỏi tiếp theo là "Vì DFA thường không thể hỗ trợ các tính năng mà NFA có thể." –

Trả lời

3

Phỏng theo ví dụ đầu tiên trong bài viết Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...):

perl -e '$n=29; ("a" x $n) =~ (("a?" x $n).("a" x $n))' 

nào mất 40 giây trên hệ thống của tôi. Sau đó, hãy làm theo số $n++ để tăng số mũ vui vẻ ...

+1

Thật kì lạ khi mọi động cơ regex không tối ưu hóa điều này. Việc giảm 'a? A?' Thành 'a {, 2}' cơ bản đến mức nó được dạy trong các lớp. –

+0

Ví dụ tổng hợp nhưng bài luận hữu ích có so sánh giữa các ngôn ngữ. – smci

3

Từ Russ của Cox tuyệt vời article: $ perl -e '("a" x 100000) =~ /^(ab?)*$/;'. Điều này dường như gây ra một segfault. Có nhiều hơn trong bài báo.

+1

Python và GNU grep không gặp vấn đề gì với điều này. 're.match (r '^ (ab?) * $', 'a' * 10000000)' –

+1

Điều này không gây ra vấn đề với cài đặt perl 5.10.1 của tôi, và dường như chạy tốt trên codepad là 5.8 http: //codepad.org/hFlqUWk8 –

+0

@Eric Strom: Tôi nghĩ tác giả đã thử nghiệm với perl 5.8.7. – MAK

0

tôi luôn luôn sử dụng regex này để phù hợp với chuỗi bên trong PHP hoặc mã nguồn JavaScript trong PHP:

~'(\\.|[^'])*'|"(\\.|[^"])*"~s 

Và nó hầu như luôn luôn thất bại trên một chuỗi rất dài (khoảng 50000 ký tự dài sẽ làm).

+0

Điều này sử dụng dấu phân cách bởi vì nó chứa cả hai loại báo giá; đã cố gắng chuyển nó sang một regex Python để kiểm tra nó, nhưng việc chạy trốn sẽ khiến tôi phát điên. Bất cứ ai có thể chuyển đổi nó? – smci

+0

Tôi chủ yếu chuyển đổi nó bằng cách sử dụng [phương pháp này do Tim Peters] (http://stackoverflow.com/questions/1472047/regex-for-triple-quote) ngoại trừ sửa đổi s (dấu chấm phù hợp với mỗi ký tự?) ... Tôi nghi ngờ rằng làm cho nó tồi tệ hơn. – smci

+0

[Áp phích này] (http://stackoverflow.com/questions/7004023/translate-the-intent-of-this-php-regex-for-multiline-strings-into-python-perl/7006231#7006231) cải thiện hiệu quả của regex của bạn, kiểm tra nó ra! – smci

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