2012-04-15 30 views
6

Giả sử tôi có một chuỗi như sau:biểu hiện thường xuyên để phù hợp với tên hàm và tất cả các đối số bằng Python

"func(arg1, arg2, arg3, arg4, ..., argn)" 

EDIT: Chức năng này không có trong một số ngôn ngữ cụ thể. Nó chỉ có định dạng này. Nếu nó làm cho nó dễ dàng hơn, đừng nghĩ nó như một lời gọi hàm, chỉ là một chuỗi.

Tôi muốn viết cụm từ thông dụng để khớp với hàm và mỗi đối số. Tôi đang viết điều này bằng Python. Các đầu ra mong muốn của việc này là:

{"function" : "func", "arg" : ["arg1", "arg2", ... , "argn"]} 

EDIT: Trong khi các đối số có thể là gọi hàm, tôi dễ dàng đệ quy có thể thử kết hợp chúng với các biểu hiện thường xuyên cùng một lần tôi có thể tạo ra loại phù hợp. Bởi điều này tôi có nghĩa là tôi có thể recurse trên chức năng với mỗi đối số. Nhưng điều này không thực sự có liên quan. Tôi là không phải cố gắng tạo một thông dịch viên, chỉ cần một cái gì đó để nhận ra các đối số.

Đây là nỗ lực của tôi lúc này:

import re 
s = "func(arg1, arg2, arg3, arg4, argn)" 
m = re.match(r"(?P<function>\w+)\s?\((?P<args>(?P<arg>\w+(,\s?)?)+)\)", s) 
print m.groupdict() 

Và đây là kết quả:

{'function': 'func', 'args': 'arg1, arg2, arg3, arg4, argn', 'arg': 'argn'} 

Chức năng phù hợp tốt, và do đó, các thiết lập tham số. Tuy nhiên, tôi dường như không thể đối sánh với các đối số riêng lẻ. Đây có phải là một vấn đề với regex của tôi, hoặc một hạn chế của Python phù hợp với biểu thức chính quy?

EDIT2: Tôi biết rằng bây giờ tôi có thể chia nhỏ các đối số sử dụng đoạn mã sau:

d["arg"] = d["args"].split(", ") 

Nhưng tôi đã tự hỏi nếu tôi có thể làm toàn bộ công việc với các biểu thức thông thường. Đặc biệt, tôi tự hỏi tại sao "arg" chỉ phù hợp với đối số cuối cùng.

EDIT3: Tôi đoán tôi (1) hy vọng tìm ra lý do tại sao Python chỉ khớp với đối số cuối cùng mọi lúc và (2) liệu tôi có thể thực hiện khớp mẫu kiểu lược đồ trong Python hay không. Hoặc nếu có một cái gì đó giống như trực quan trong Python như là mô hình kiểu lược đồ khớp. Tôi nhìn vào mô-đun ast, và cú pháp của nó là cực kỳ phức tạp.

+1

Chức năng này có gọi bằng một số ngôn ngữ cụ thể không? Bạn không nên sử dụng cụm từ thông dụng để phân tích ngôn ngữ mà trình phân tích cú pháp chính xác/đầy đủ đã tồn tại ... – Borealid

+0

Bạn không thể thực hiện điều này bằng các biểu thức chính quy (giả sử bạn muốn khớp với các đối số riêng lẻ).). Bạn cần một trình phân tích cú pháp thực tế. Nếu bạn nhấn mạnh vào viết của riêng bạn, sau đó đọc này: http://effbot.org/zone/simple-iterator-parser.htm – Wes

+0

Bạn có thể muốn kiểm tra [pyparsing] (http://pyparsing.wikispaces.com/) nếu bạn đang có kế hoạch làm một cái gì đó phức tạp hơn. –

Trả lời

4

Hình như bạn 90% đó, tại sao không chỉ trao đổi các argargs nhóm và làm:

import re 

fn_match = re.match(r"(?P<function>\w+)\s?\((?P<arg>(?P<args>\w+(,\s?)?)+)\)", s) 
fn_dict = fn_match.groupdict() 
del fn_dict['args'] 
fn_dict['arg'] = [arg.strip() for arg in fn_dict['arg'].split(',')] 
+0

Tôi đang cố chụp toàn bộ thứ như một regex. Điều đó là không thể? – BlackSheep

+0

Không để có được danh sách kết quả của args mà bạn muốn. Tại sao chỉ sử dụng một con dao quân đội swiss khi bạn có một hộp công cụ toàn bộ? – mVChr

7

Cụm từ thông dụng không thể phân tích ngôn ngữ lập trình phức tạp.

Nếu bạn chỉ đang cố gắng phân tích cú pháp Python, tôi khuyên bạn nên xem mô-đun ast, sẽ phân tích cú pháp đó cho bạn.

+0

Tôi không cố gắng phân tích cú pháp Python, chỉ cần nắm bắt một cú pháp rất cụ thể. Từ ít tôi đọc, có vẻ như mô-đun ast là (1) cụ thể cho Python, và (2) là khá phức tạp cho những gì tôi đang cố gắng để làm. – BlackSheep

1

Để trả lời phần cuối của câu hỏi của bạn: Số Python không có bất cứ điều gì tương tự như Đề án "khớp", cũng không có mẫu phù hợp như ML/Haskell. Điều gần nhất là khả năng hủy cấu trúc những thứ như thế này

>>> (a, [b, c, (d, e)]) = (1, [9, 4, (45, 8)]) 
>>> e 
8 

Và để trích xuất đầu và đuôi của danh sách (bằng Python 3.x) như thế này ...

>>> head, *tail = [1,2,3,4,5] 
>>> tail 
[2, 3, 4, 5] 

Có một số mô-đun nổi xung quanh khớp với mẫu thực trong python, nhưng tôi không thể xác minh chất lượng của chúng.

Nếu tôi phải thực hiện, tôi sẽ thực hiện nó một chút khác biệt - có thể có khả năng nhập một loại và đối số tùy chọn (ví dụ: độ dài hoặc nội dung chính xác) và chức năng để gọi nếu nó khớp, match ([list, length = 3, check = (3, str), func]) và nó sẽ khớp (danh sách _ _ somestr) và func với somestr trong phạm vi, và bạn cũng có thể thêm các mẫu khác.

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