2012-10-22 40 views
5

Giả sử bạn muốn thực hiện tìm kiếm biểu thức chính quy và trích xuất qua một đường ống, nhưng mẫu có thể vượt qua nhiều dòng, Cách thực hiện? Có thể một thư viện biểu thức chính quy hoạt động cho một luồng?cụm từ thông dụng trên luồng thay vì chuỗi?

Tôi hy vọng thực hiện công việc này bằng thư viện Python? Nhưng bất kỳ giải pháp nào cũng được, một thư viện không phải là một công cụ dòng cmd.

BTW, tôi biết cách giải quyết vấn đề hiện tại của mình, chỉ cần tìm giải pháp chung.

Nếu không có libray như vậy tồn tại, tại sao thư viện thông thường không thể làm việc với luồng được cung cấp cho thuật toán toán học thông thường không bao giờ cần quét ngược.

+2

Với những gì ngôn ngữ? – user1610015

+0

Bạn có thể gửi một số đầu vào mẫu và đầu ra dự kiến ​​của bạn? – pogo

+1

Bạn có thể thực hiện kết hợp regex trên toàn tuyến, nhưng thông thường, bạn sẽ cần mọi thứ để ở đó để phù hợp để xảy ra. – nhahtdh

Trả lời

6

Nếu bạn đang theo đuổi một giải pháp chung, thuật toán của bạn sẽ cần phải tìm một cái gì đó như:

  1. đọc một đoạn của con suối vào một bộ đệm.
  2. Tìm kiếm các regexp trong bộ đệm
  3. Nếu mô hình phù hợp, làm bất cứ điều gì bạn muốn với trận đấu, loại bỏ sự khởi đầu của bộ đệm lên đến match.end() và đi đến bước 2.
  4. Nếu mô hình không phù hợp , mở rộng bộ đệm có nhiều dữ liệu hơn từ luồng

Điều này có thể kết thúc bằng cách sử dụng nhiều bộ nhớ nếu không tìm thấy kết quả phù hợp (xem xét cố gắng kết hợp .*x làm regexp nhiều dòng trong một tệp lớn, trong đó chỉ x là ký tự cuối cùng).

Nếu bạn biết thêm về regexp, bạn có thể có các trường hợp khác mà bạn có thể loại bỏ một phần bộ đệm.

+0

đây là một thuật toán đơn giản, tôi nghĩ rằng nó sẽ làm việc cho tôi. – user1733712

+0

Nhìn vào câu trả lời của @ ITNinja, thuật toán tôi đưa ra cũng không hoàn hảo. Ví dụ, nếu bạn có một biểu thức 'x *' và bộ đệm kết thúc bằng 'x', thuật toán có thể cho bạn kết quả sai nếu luồng chứa nhiều ký tự' x' hơn. Hy vọng rằng nó là đủ để cung cấp cho bạn một số ý tưởng về cách bạn có thể xử lý các tình huống như vậy với thư viện 're'. –

+0

Bây giờ tôi đã nhận được điểm của @ ITNinja. Thật vậy, một khi '. ​​*' Trình bày, tất cả các luồng cần được đệm rất có thể.Nhưng các thư viện hoạt động trên luồng vẫn có lợi thế nếu được thiết kế đúng cách, chúng tạo ra và tạo dữ liệu cho phù hợp. Nhưng việc thực hiện thích hợp cần phải viết lại thư viện RE ở mức độ thấp hơn mà là vượt ra ngoài patinet và khả năng của tôi. – user1733712

-1

Tôi không tin rằng có thể sử dụng cụm từ thông dụng trên luồng, vì không có toàn bộ dữ liệu, bạn không thể tạo kết quả tích cực. Điều này có nghĩa là bạn sẽ chỉ có một trận đấu có thể xảy ra.

Tuy nhiên, như @James Henstridge đã nêu, bạn có thể sử dụng bộ đệm để khắc phục điều này.

+2

Điều này không đúng. Một regex đơn giản là một DFA. Mỗi ký tự đầu vào là một quá trình chuyển đổi trạng thái trong DFA đó. Một (các) chuyển đổi cụ thể biểu thị một trận đấu. Chặn các tính năng nâng cao hoặc các ràng buộc về hiệu suất triển khai, không cần chuỗi đầy đủ để đánh giá DFA trên một chuỗi. – alexei

2

Tôi đã giải quyết được sự cố tương tự để tìm kiếm luồng bằng cách sử dụng đối sánh mẫu cổ điển. Bạn có thể muốn phân lớp lớp Matcher của giải pháp của tôi streamsearch-py và thực hiện đối sánh regex trong bộ đệm. Hãy xem kmp_example.py được bao gồm bên dưới để biết mẫu. Nếu nó quay ra cổ điển phù hợp với Knuth-Morris-Pratt là tất cả các bạn cần, sau đó vấn đề của bạn sẽ được giải quyết ngay bây giờ với ít thư viện mã nguồn mở này :-)

#!/usr/bin/env python 

# Copyright 2014-2015 @gitagon. For alternative licenses contact the author. 
# 
# This file is part of streamsearch-py. 
# streamsearch-py is free software: you can redistribute it and/or modify 
# it under the terms of the GNU Affero General Public License as published by 
# the Free Software Foundation, either version 3 of the License, or 
# (at your option) any later version. 
# 
# streamsearch-py is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
# GNU Affero General Public License for more details. 
# You should have received a copy of the GNU Affero General Public License 
# along with streamsearch-py. If not, see <http://www.gnu.org/licenses/>. 


from streamsearch.matcher_kmp import MatcherKMP 
from streamsearch.buffer_reader import BufferReader 

class StringReader(): 
    """for providing an example read() from string required by BufferReader""" 
    def __init__(self, string): 
     self.s = string 
     self.i = 0 

    def read(self, buf, cnt): 
     if self.i >= len(self.s): return -1 
     r = self.s[self.i] 
     buf[0] = r 
     result = 1 
     print "read @%s" % self.i, chr(r), "->", result 
     self.i+=1 
     return result 

def main(): 

    w = bytearray("abbab") 
    print "pattern of length %i:" % len(w), w 
    s = bytearray("aabbaabbabababbbc") 
    print "text:", s 
    m = MatcherKMP(w) 
    r = StringReader(s) 
    b = BufferReader(r.read, 200) 
    m.find(b) 
    print "found:%s, pos=%s " % (m.found(), m.get_index()) 


if __name__ == '__main__': 
    main() 

ra là

pattern of length 5: abbab 
text: aabbaabbabababbbc 
read @0 a -> 1 
read @1 a -> 1 
read @2 b -> 1 
read @3 b -> 1 
read @4 a -> 1 
read @5 a -> 1 
read @6 b -> 1 
read @7 b -> 1 
read @8 a -> 1 
read @9 b -> 1 
found:True, pos=5 
+1

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. –

+0

đúng. đã dán 'kmp_example.py' – gitagon

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