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?
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?
Câu trả lời:
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.
Đâ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 đó.
re.compile
tạ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.
#
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.
#
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 )
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.
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
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à đủ.
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ể đó).
Nhận xét nên thêm thông tin hữu ích không rõ ràng từ mã.
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.
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
Đương nhiên, lớp của bạn có thể lưu trữ một số regex.