2010-08-09 28 views
13

Tôi đang cố gắng tạo một hàm Python có thể mô tả bằng tiếng Anh đơn giản về cụm từ thông dụng và trả lại biểu thức chính quy cho người gọi.có cần một cách khai báo biểu thức chính quy hơn không? :)

Hiện tại tôi đang nghĩ về mô tả ở định dạng YAML. Vì vậy, chúng ta có thể lưu trữ mô tả dưới dạng biến chuỗi thô, được chuyển sang hàm khác và đầu ra của hàm đó sau đó được truyền cho mô-đun 'tái'. Sau đây là một ví dụ khá đơn giản:

# a(b|c)d+e* 
re1 = """ 
- literal: 'a' 
- one_of: 'b,c' 
- one_or_more_of: 'd' 
- zero_or_more_of: 'e' 
""" 
myre = re.compile(getRegex(re1)) 
myre.search(...) 

, vv

Có ai nghĩ rằng một cái gì đó thuộc loại này sẽ được sử dụng rộng rãi hơn? Bạn có biết các gói hiện có có thể thực hiện được không? Những giới hạn mà bạn thấy trong cách tiếp cận này là gì? Có ai nghĩ rằng, có chuỗi khai báo trong mã, sẽ làm cho nó dễ bảo trì hơn?

+0

JSON hoặc XML có thể? DTD hoặc XSD cũng có thể decribe một cấu trúc dữ liệu tốt. – codymanix

+7

Vì vậy, thay vì một regex phức tạp tham gia một dòng toàn bộ, nó sẽ mất một trang toàn bộ :) –

+4

Những người biết biểu thức thông thường được thoải mái với nó, nhưng để mọi người khác nó trông giống như bảng chữ cái đã ném lên. Đây có thể là một vấn đề, nhưng tôi không chắc chắn. Sau khi tất cả, bạn có thể nói điều tương tự của ngôn ngữ lập trình cho những người chương trình vs perople những người không. Nó có thể là tốt đẹp để làm điều đó với các đối tượng và chức năng instad của dây, nhưng tôi không chắc chắn những gì cách tốt nhất để thực hiện đó sẽ là. 1 cho sự đổi mới tất cả như nhau. – psicopoo

Trả lời

2

Đối với các nhà phát triển đang cố gắng để viết biểu thức thông thường mà rất dễ để mò mẫm và duy trì, tôi tự hỏi liệu phương pháp tiếp cận này sẽ cung cấp bất cứ điều gì mà re.VERBOSE không cung cấp.

Đối với người mới bắt đầu, ý tưởng của bạn có thể có một số khiếu nại. Tuy nhiên, trước khi bạn đi xuống con đường này, bạn có thể thử giả lập cú pháp khai báo của bạn sẽ trông như thế nào đối với các cụm từ thông dụng phức tạp hơn bằng cách chụp các nhóm, neo, các xác nhận phía trước, v.v. Một thách thức là bạn có thể kết thúc bằng một cú pháp khai báo khó nhớ như ngôn ngữ chính quy.

Bạn cũng có thể nghĩ về các cách thay thế để diễn tả mọi thứ. Ví dụ, ý nghĩ đầu tiên xảy ra với tôi là thể hiện một regex bằng cách sử dụng các hàm có tên ngắn, dễ nhớ. Ví dụ:

from refunc import * 

pattern = Compile(
    'a', 
    Capture(
     Choices('b', 'c'), 
     N_of('d', 1, Infin()), 
     N_of('e', 0, Infin()), 
    ), 
    Look_ahead('foo'), 
) 

Nhưng khi tôi thấy điều đó trong thực tế, nó trông giống như một nỗi đau đối với tôi. Có nhiều khía cạnh của regex khá trực quan - ví dụ: + có nghĩa là "một hoặc nhiều". Một lựa chọn sẽ là một phương pháp lai, cho phép người dùng của bạn trộn các phần của regex đã đơn giản với các hàm cho các bit bí truyền hơn.

pattern = Compile(
    'a', 
    Capture(
     '[bc]', 
     'd+', 
     'e*', 
    ), 
    Look_ahead('foo'), 
) 

Tôi sẽ thêm rằng theo kinh nghiệm của tôi, biểu thức chính quy là về việc học một quy trình suy nghĩ. Làm quen với cú pháp là phần dễ dàng.

6

Điều này thực sự khá giống nhau (giống hệt nhau?) Với cách trình phân tích cú pháp/trình phân tích cú pháp hoạt động. Nếu bạn đã có một ngữ pháp được định nghĩa thì bạn có thể viết một trình phân tích cú pháp không có quá nhiều rắc rối. Ví dụ: bạn có thể viết một cái gì đó như thế này:

<expression> :: == <rule> | <rule> <expression> | <rule> " followed by " <expression> 
<rule>  :: == <val> | <qty> <val> 
<qty>  :: == "literal" | "one" | "one of" | "one or more of" | "zero or more of" 
<val>  :: == "a" | "b" | "c" | "d" | ... | "Z" | 

Đó là hư không gần mô tả hoàn hảo. Để biết thêm thông tin, hãy xem this BNF of the regex language. Sau đó, bạn có thể xem các biểu tượng lexingparsing.

Nếu bạn đã làm theo cách này, bạn có thể gần hơn một chút với Natural Language/phiên bản tiếng Anh của các regex.


Tôi có thể thấy một công cụ như thế này hữu ích, nhưng như đã nói trước đây, chủ yếu cho người mới bắt đầu. Giới hạn chính của phương pháp này là số lượng mã bạn phải viết để dịch ngôn ngữ thành regex (và/hoặc ngược lại). Mặt khác, tôi nghĩ một công cụ dịch thuật hai chiều sẽ thực sự lý tưởng hơn và sử dụng nhiều hơn. Có thể lấy một regex và biến nó thành tiếng Anh có thể hữu ích hơn nhiều để phát hiện lỗi.

Tất nhiên, không mất quá nhiều thời gian để lấy regex vì cú pháp thường là terse và hầu hết ý nghĩa là khá tự giải thích, ít nhất là nếu bạn sử dụng | hoặc || dưới dạng OR bằng ngôn ngữ của bạn và bạn nghĩ * là nhân với 0-N, + khi thêm 0-N.

Mặc dù đôi khi tôi sẽ không nhớ gõ "tìm một hoặc nhiều 'a' tiếp theo là ba chữ số hoặc 'b' rồi 'c'"

+0

Để trả lời cho bạn 'Có thể lấy regex và biến nó thành tiếng Anh có thể hữu ích hơn nhiều trong việc phát hiện lỗi.', hãy thử 're.DEBUG' tham số với python trong chế độ repl. – Daenyth

+0

@Denyeny - Tôi biết về chế độ đó, mặc dù tôi đã không có nguyên nhân để sử dụng nó, và tôi không thể nói nó tốt hơn nhiều so với regex gốc, trừ khi đó là một regex cực kỳ phức tạp. –

6

Hãy xem tại pyparsing. Nhiều người trong số các vấn đề mà bạn mô tả với RE's là những vấn đề khiến tôi viết gói đó.

Dưới đây là một số tính năng cụ thể của pyparsing từ chương sách điện tử O'Reilly "What's so special about pyparsing?".

+1

Bạn đã đánh bại tôi một giây! BTW, cảm ơn vì đã viết pyparsing :) –

2

có lẽ không chính xác những gì bạn đang yêu cầu, nhưng có một cách làm thế nào để viết regexes cách dễ đọc hơn (VERBOSE, ngay X cờ):

rex_name = re.compile(""" 
    [A-Za-z] # first letter 
    [a-z]+  # the rest 
""", re.X) 

rex_name.match('Joe') 
Các vấn đề liên quan