2009-02-28 39 views
11

Tình trạng khó xử của tôi: Tôi đang chuyển hàm của tôi một chuỗi mà tôi cần sau đó thực hiện nhiều thao tác regex. Logic là nếu có một trận đấu trong regex đầu tiên, làm một điều. Nếu không có trận đấu, hãy kiểm tra trận đấu với trận đấu thứ hai và làm điều gì đó khác, nếu không kiểm tra trận đấu thứ ba, v.v. Tôi có thể làm một cái gì đó như thế này:Làm thế nào để thác chính xác thông qua nhiều câu lệnh regex trong Python

if re.match('regex1', string): 
    match = re.match('regex1', string) 
    # Manipulate match.group(n) and return 
elif re.match('regex2', string): 
    match = re.match('regex2', string) 
    # Do second manipulation 
[etc.] 

Tuy nhiên, điều này cảm thấy không cần thiết tiết, và thường khi đó là trường hợp nó có nghĩa là có một cách tốt hơn là tôi hoặc là nhìn ra hoặc chưa biết về.

Có ai có đề xuất về cách tốt hơn để thực hiện việc này hay không (tốt hơn từ quan điểm mã xuất hiện, quan điểm sử dụng bộ nhớ hoặc cả hai)?

+0

Dupicate: http://stackoverflow.com/questions/122277/how-do-you-translate-this-regular-expression-idiom-from-perl-into-python –

Trả lời

10

câu hỏi tương tự từ phía sau trong tháng chín: How do you translate this regular-expression idiom from Perl into Python?

Sử dụng các biến toàn cầu trong một mô-đun có lẽ không phải là cách tốt nhất để làm điều đó, nhưng chuyển đổi nó thành một lớp:

import re 

class Re(object): 
    def __init__(self): 
    self.last_match = None 
    def match(self,pattern,text): 
    self.last_match = re.match(pattern,text) 
    return self.last_match 
    def search(self,pattern,text): 
    self.last_match = re.search(pattern,text) 
    return self.last_match 

gre = Re() 
if gre.match(r'foo',text): 
    # do something with gre.last_match 
elif gre.match(r'bar',text): 
    # do something with gre.last_match 
else: 
    # do something else 
+0

Cảm ơn bạn đã liên kết! Tôi không tìm thấy chủ đề đó trong tìm kiếm của mình, nhưng đó là một điểm cho những gì tôi đang cố gắng làm. Tôi thích ý tưởng sử dụng một lớp hơn là một mô-đun, quá. –

1

Hmm ... bạn có thể sử dụng một cái gì đó với with xây dựng ... um

class rewrapper() 
    def __init__(self, pattern, target): 
     something 

    def __enter__(self): 
     something 

    def __exit__(self): 
     something 


with rewrapper("regex1", string) as match: 
    etc 

with rewrapper("regex2", string) as match: 
    and so forth 
0

Liệu các thao tác cho mỗi regex tương tự? Nếu vậy, hãy thử này:

for regex in ('regex1', 'regex2', 'regex3', 'regex4'): 
    match = re.match(regex, string) 
    if match: 
     # Manipulate match.group(n) 
     return result 
+0

Thật không may các thao tác khác nhau cho các regex khác nhau; nhìn lại, tôi nên đã xác định rằng trong câu hỏi. –

0

Đây regexs và các trận đấu của bạn không được lặp lại hai lần:

match = re.match('regex1', string) 
if match: 
    # do stuff 
    return 

match = re.match('regex2', string) 
if match: 
    # do stuff 
    return 
24

Nói chung, trong các loại tình huống này, bạn muốn thực hiện mã "dữ liệu điều khiển". Tức là, đưa thông tin quan trọng vào một thùng chứa và lặp lại thông tin đó.

Trong trường hợp của bạn, thông tin quan trọng là các cặp (chuỗi, hàm).

import re 

def fun1(): 
    print('fun1') 

def fun2(): 
    print('fun2') 

def fun3(): 
    print('fun3') 

regex_handlers = [ 
    (r'regex1', fun1), 
    (r'regex2', fun2), 
    (r'regex3', fun3) 
    ] 

def example(string): 
    for regex, fun in regex_handlers: 
     if re.match(regex, string): 
      fun() # call the function 
      break 

example('regex2') 
+0

Cảm ơn đề xuất này! Đây là những gì tôi có thể sẽ kết thúc, nhưng phiên bản ghi đè của mô-đun lại phù hợp hơn một chút cho dự án này. –

2

tôi đã cùng một vấn đề như của bạn. Here's giải pháp của tôi:

import re 

regexp = { 
    'key1': re.compile(r'regexp1'), 
    'key2': re.compile(r'regexp2'), 
    'key3': re.compile(r'regexp3'), 
    # ... 
} 

def test_all_regexp(string): 
    for key, pattern in regexp.items(): 
     m = pattern.match(string) 
     if m: 
      # do what you want 
      break 

It'sa chút thay đổi giải pháp từ câu trả lời của Extracting info from large structured text files

+0

Từ điển không đảm bảo đặt hàng. Bạn có thể nên sử dụng một chuỗi thay vì một dict để có được hành vi dự đoán được. –

0
class RegexStore(object): 
    _searches = None 

    def __init__(self, pat_list): 
     # build RegEx searches 
     self._searches = [(name,re.compile(pat, re.VERBOSE)) for 
         name,pat in pat_list] 

    def match(self, text): 
     match_all = ((x,y.match(text)) for x,y in self._searches) 
     try: 
     return ifilter(op.itemgetter(1), match_all).next() 
     except StopIteration, e: 
     # instead of 'name', in first arg, return bad 'text' line 
     return (text,None) 

Bạn có thể sử dụng lớp này như sau:

rs = RegexStore((('pat1', r'.*STRING1.*'), 
        ('pat2', r'.*STRING2.*'))) 
name,match = rs.match("MY SAMPLE STRING1") 

if name == 'pat1': 
    print 'found pat1' 
elif name == 'pat2': 
    print 'found pat2' 
Các vấn đề liên quan