Bình luận biểu thức chính quy


11

Có bất kỳ thực tiễn phổ biến nào để nhận xét các biểu thức chính quy: nhận xét nội tuyến đề cập đến phần khác nhau của RegEx hoặc nhận xét chung cho tất cả các biểu thức không?


2
Có nhưng bạn cần phải cụ thể hơn. Ví dụ Bash hỗ trợ các bình luận nội tuyến và Python cung cấp các biểu thức chính quy dài dòng.
sakisk

6
Nguyên tắc nhỏ của tôi đối với các biểu thức chính quy là: nếu bạn cần bình luận biểu thức chính quy, nó quá phức tạp.
zzzzBov

1
Và luôn luôn bao gồm liên kết này: regexcrossword.com
Kieveli

Tôi không nhất thiết phải đồng ý rằng nếu bạn phải bình luận, nó quá phức tạp. Một regex phức tạp vẫn có thể giúp bạn tiết kiệm hàng tấn mã mệnh lệnh bắt mắt. Sử dụng một tên biến mô tả tốt để gán regex cho. Nếu vẫn chưa đủ rõ ràng, hãy sử dụng một nhận xét ngắn gọn để truyền đạt ý định ban đầu đằng sau biểu thức thông thường.
Craig

Câu trả lời:


10

Theo quan điểm của tôi, một thực tiễn tốt là nêu chính xác trong các bình luận ý tưởng chung của biểu thức chính quy là gì. Điều này giúp các nhà phát triển khác (hoặc đôi khi là chính bạn) gặp rắc rối khi sao chép regex trong trình phân tích cú pháp như RegExr , chỉ để hiểu những gì nó làm.


2
RegExr sẽ xảy ra bằng mọi cách, trừ khi nhà phát triển là một người am hiểu regex. Nhưng tôi đồng ý với việc cung cấp một mô tả chung; đó là những gì tôi làm với regexes của tôi.
Robert Harvey

3
+1: Bất cứ điều gì chi tiết hơn sẽ kết thúc là một khóa học sự cố trong regex như một nhận xét.
Matt

Câu trả lời này và các ý kiến ​​@zzzzBov có ý nghĩa.
m0nhawk

1
Nó không chỉ tiết kiệm sự rắc rối của việc kiểm tra biểu thức thông thường để hiểu nó, mà còn làm cho ý định của lập trình viên ban đầu rõ ràng, đặc biệt là khả năng khác biệt là lập trình viên ban đầu có biểu thức chính quy sai vòng thời gian linh hoạt. Phải nói rằng, trong rất nhiều trường hợp, việc gán regex cho một tên biến tốt có thể tính một chặng đường dài hướng tới việc cung cấp tài liệu đầy đủ về ý định.
Craig

9

Đây là một câu trả lời cụ thể về ngôn ngữ, nhưng không có ngôn ngữ nào được nêu trong câu hỏi.

Cuốn sách "Lặn sâu vào Python" đề xuất thực hiện các bình luận bằng cách sử dụng Biểu thức chính quy Verbose :

Python cho phép bạn làm điều này với một cái gì đó gọi là biểu thức chính quy dài. Biểu thức chính quy dài dòng khác với biểu thức chính quy nhỏ gọn theo hai cách:

  • Khoảng trắng được bỏ qua. Không gian, tab và trả về vận chuyển không được khớp với khoảng trắng, tab và trả về vận chuyển. Chúng không phù hợp chút nào. (Nếu bạn muốn khớp một khoảng trắng trong một biểu thức chính quy dài dòng, bạn sẽ cần phải thoát nó bằng cách đặt dấu gạch chéo ngược trước nó.)
  • Bình luận bị bỏ qua. Một nhận xét trong một biểu thức chính quy dài giống như một nhận xét trong mã Python: nó bắt đầu bằng một #ký tự và đi cho đến cuối dòng. Trong trường hợp này, đó là một nhận xét trong chuỗi nhiều dòng thay vì trong mã nguồn của bạn, nhưng nó hoạt động theo cùng một cách.

Thí dụ:

>>> pattern = """
^                   # beginning of string
M{0,4}              # thousands - 0 to 4 M's
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                    #            or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                    #        or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                    #        or 5-8 (V, followed by 0 to 3 I's)
$                   # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE)                1

Nguồn và thông tin chi tiết tại đây

Phương pháp này có một nhược điểm nhỏ là người gọi phải biết rằng mẫu được viết theo định dạng dài dòng và gọi nó theo đó.


2
Thay vì lưu trữ mẫu trong một biến, bạn có thể sử dụng re.compiletại điểm bạn xác định mẫu và chỉ lưu trữ đối tượng kết quả. Theo cách đó, các cờ biên dịch mẫu (bao gồm re.VERBOSE) không cần phải tách khỏi mẫu.
John Bartholomew

Câu trả lời thực sự hữu ích, cảm ơn! Nhưng làm thế nào tôi có thể khớp với #nếu tôi đang sử dụng cờ dài dòng? Nhân tiện: các liên kết nguồn dường như không hoạt động.
winklerrr

Được rồi, vì vậy #có thể được xuất hiện nghĩa là khi bên trong một lớp nhân vật: [#](nguồn: docs.python.org/3/library/re.html#re.X )
winklerrr

8

Thông thường, tôi sẽ viết một regex và không giải thích các phần riêng lẻ của regex, mà là mục đích của nó là gì. Đó là những gì và tại sao. Điều này hơi giống với câu hỏi "Nhận xét của tôi nên như thế nào?" người ta sẽ nói " Đừng viết những gì mã đang làm, hãy viết tại sao mã đó lại làm những gì nó làm "

// Strip the leading "?" and remove the query parameters "offset=<integer>" & "count=<integer> so we have a pattern of the request"          
var search = location.search.substring(1).replace(/offset=[0-9]+?&/g, "").replace(/count=[0-9]+?&/g, "");

Trừ khi bạn đang cố gắng dạy ai đó về regex thông qua các nhận xét trong mã, tôi không nghĩ giải thích từng phần riêng lẻ sẽ làm gì. Khi làm việc với các lập trình viên khác, bạn có thể giả định một cách an toàn rằng người ta sẽ biết một cái gì đó là biểu thức chính quy toàn cầu.


3
bạn sẽ ngạc nhiên ...
Matt

6

Tôi đoán nó thực sự phụ thuộc vào cách bạn đặt regex lại với nhau. Nói chung, tôi nghĩ rằng sẽ là một ý tưởng tồi khi đặt bình luận trong chính chuỗi regex thực tế (không thể thực hiện được trong hầu hết các kịch bản, theo như tôi biết). Nếu bạn thực sự cần bình luận các phần cụ thể của một biểu thức chính quy (bạn có đang cố gắng dạy ai đó không?), Thì hãy chia từng đoạn thành các chuỗi riêng biệt trên các dòng riêng của chúng và nhận xét từng dòng bằng quy trình nhận xét thông thường cho ngôn ngữ lập trình của bạn. Mặt khác, câu trả lời của pleinolijf là khá tốt.

thí dụ:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter

4

Tôi thường định nghĩa một hằng chuỗi có tên mô tả mục đích tổng thể của biểu thức chính quy.

Ví dụ:

const string FloatingPointNumberPattern = @"[-+]?[0-9]*\.?[0-9]+";

Bạn có thể thêm một nhận xét phía trên hằng số này để mô tả nó, nhưng thông thường tên hằng số là đủ.


1
Một điều nữa tôi thích về câu trả lời này là nếu nó được sử dụng ở nhiều nơi, mục đích cũng phải được thực hiện - không quên bình luận.
J Trana

3

Trong một số trường hợp, (các) nhà phát triển có thể đang sử dụng các biểu thức chính quy để khớp văn bản bên ngoài miền thông thường của họ. Các nhà phát triển ban đầu có thể đã trải qua rất nhiều lần lặp lại nắm bắt các trường hợp cạnh khác nhau mà chỉ có thể được phát hiện thông qua quá trình lặp đó. Do đó, các nhà phát triển tiếp theo có thể không nhận thức được rất nhiều trường hợp cạnh mà (các) nhà phát triển ban đầu đã xử lý, ngay cả khi họ biết về trường hợp chung.

Trong các trường hợp như vậy, có thể đáng để ghi lại các ví dụ về các biến thể. Vị trí của tài liệu này có thể thay đổi tùy thuộc vào số lượng (ví dụ, không nhất thiết phải có trong mã).

Một cách để tiếp cận là giả định rằng các nhà phát triển trong tương lai sẽ chỉ có kiến ​​thức cơ bản, như cách các biểu thức chính quy hoạt động, nhưng không có bất kỳ kiến ​​thức nào mà bạn (1) có trước khi phát triển các biểu thức chính quy mà không nhất thiết phải biết nhà phát triển trong tương lai hoặc (2) kiến ​​thức mà bạn có được trong quá trình phát triển (ví dụ: các trường hợp cạnh đã được phát hiện).

Ví dụ: nếu trong quá trình phát triển, bạn nói điều gì đó như "Ồ, tôi không biết rằng X có thể có dạng này", thì đáng để ghi lại điều đó (và có thể là một phần của biểu thức chính xử lý biến thể đó).


2

Nhận xét nên thêm thông tin hữu ích không rõ ràng từ mã.

  1. Làm cho nó dễ hiểu những gì biểu thức được cho là phải làm ở mức yêu cầu, trong chính mã hoặc trong một nhận xét. Ý định đằng sau biểu thức là gì, là để xác thực địa chỉ email hoặc chọn số điện thoại của Canada.
  2. Làm cho nó dễ hiểu những gì biểu thức đang thực sự làm, tức là những gì biểu thức đánh giá. Trước tiên hãy cố gắng làm rõ bằng cách tách biểu thức, nếu trước tiên bạn kiểm tra tất cả các dấu gạch nối sau đó xóa tất cả các số sau đó làm cho biểu thức hai phần với các biến giữ các giá trị trung gian, nó sẽ giúp đọc dễ dàng hơn và người đọc sẽ dễ đọc hơn có thể bước qua logic của bạn từng bước một. (Có một câu trả lời nổi tiếng cho một câu hỏi về SE, nơi ai đó đang cố giải mã một số mã cũ liên quan đến thao tác bit '>> và tìm hiểu xem các cờ nhất định được đặt ở đâu mà câu trả lời không chỉ là mã thực sự làm gì mà còn như thế nào câu hỏi của authour sẽ đi về việc giải mã loại mã này trong tương lai, đó chính xác là những gì tôi đang cố gắng mô tả nhưng tôi có thể '

Có một vài ứng dụng cần mỗi chu kỳ cuối cùng, nếu bạn phù hợp với các tập dữ liệu lớn thì có thể có cách tốt hơn, có thể không, nhưng đối với hầu hết mọi thứ, thời gian thực hiện thêm không phải là vấn đề lớn.

Và hãy nhớ người tiếp theo bắt gặp mã của bạn và sửa một lỗi có thể là bạn sau sáu tháng nữa và không có cách nào bạn sẽ nhớ những gì nó phải làm.


1

Trích xuất RegEx thành một lớp riêng biệt thành một tên có ý nghĩa. Sau đó, tôi sẽ ghi lại mã bằng các bài kiểm tra tự động.

Điều này sẽ đảm bảo

  • Mã thực sự hoạt động - cũng cho các trường hợp góc
  • Đảm bảo rằng một "lỗi" nhanh chóng không làm hỏng nhiều trường hợp góc
  • Có thể tối ưu hóa tài liệu khi quay lui bị vô hiệu hóa

Đương nhiên, lớp của bạn có thể lưu trữ một số regex.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.