Komentowanie wyrażeń regularnych

11

Czy są jakieś powszechne praktyki komentowania wyrażeń regularnych: komentarze wstawiane odnoszące się do innej części RegEx lub komentarze ogólne dla wszystkich wyrażeń?

m0nhawk
źródło
2
Są, ale musisz być bardziej szczegółowy. Na przykład Bash obsługuje wbudowane komentarze, a Python oferuje pełne wyrażenia regularne.
sakisk,
6
Moja ogólna zasada dotycząca wyrażeń regularnych jest taka: jeśli chcesz skomentować wyrażenie regularne, jest to zbyt skomplikowane.
zzzzBov,
1
I zawsze dołączaj ten link: regexcrossword.com
Kieveli
Niekoniecznie zgadzam się, że jeśli musisz to skomentować, jest to zbyt skomplikowane. Skomplikowane wyrażenie regularne wciąż pozwala zaoszczędzić mnóstwo oszałamiającego kodu imperatywnego. Użyj dobrej nazwy zmiennej opisowej, aby przypisać wyrażenie regularne. Jeśli nadal nie jest wystarczająco jasne, użyj krótkiego komentarza, aby przekazać pierwotne zamiary wyrażenia regularnego.
Craig

Odpowiedzi:

10

Moim zdaniem dobrą praktyką jest zwięzłe stwierdzenie w komentarzach, jaka jest ogólna idea wyrażenia regularnego. Oszczędza to innym programistom (lub czasem samemu) problemów z kopiowaniem i wklejaniem wyrażenia regularnego w parserze takim jak RegExr , tylko po to, aby zrozumieć, co robi.

pleinolijf
źródło
2
RegExr i tak się wydarzy, chyba że dev jest znawcą wyrażeń regularnych. Ale zgadzam się z ogólnym opisem; to właśnie robię z moimi wyrażeniami regularnymi.
Robert Harvey
3
+1: Coś bardziej szczegółowego zakończy się awarią wyrażenia regularnego jako komentarz.
Matt
Ta odpowiedź i komentarze @zzzzBov mają sens.
m0nhawk
1
Nie tylko pozwala uniknąć kłopotliwego sprawdzania wyrażeń regularnych, aby je zrozumieć, ale także wyraźnie wyjaśnia intencję oryginalnego programisty, szczególnie biorąc pod uwagę wyraźną możliwość, że pierwotny programista sam źle wyraził wyrażenie regularne podczas rundy początkowej. To powiedziawszy, w wielu przypadkach przypisanie wyrażenia regularnego do dobrej nazwy zmiennej może mieć duże znaczenie dla zapewnienia odpowiedniej dokumentacji intencji.
Craig
9

Jest to odpowiedź specyficzna dla języka, ale pytanie nie zawiera żadnego języka.

Książka „Dive Into Python” sugeruje implementację komentarzy przy użyciu pełnych wyrażeń regularnych :

Python pozwala to zrobić z czymś zwanym pełnymi wyrażeniami regularnymi. Pełne wyrażenie regularne różni się od zwartego wyrażenia regularnego na dwa sposoby:

  • Białe znaki są ignorowane. Spacje, tabulatory i znaki powrotu karetki nie są dopasowywane jako spacje, tabulatory i znaki powrotu karetki. W ogóle nie są dopasowane. (Jeśli chcesz dopasować spację do pełnego wyrażenia regularnego, musisz uciec od niego, umieszczając przed nim odwrotny ukośnik).
  • Komentarze są ignorowane. Komentarz w pełnym wyrażeniu regularnym jest jak komentarz w kodzie Pythona: zaczyna się od #znaku i przechodzi do końca wiersza. W tym przypadku jest to komentarz w ciągu kilku wierszy zamiast w kodzie źródłowym, ale działa w ten sam sposób.

Przykład:

>>> 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

Źródło i dalsze szczegóły tutaj

Ta metoda ma niewielką wadę polegającą na tym, że osoba dzwoniąca musi wiedzieć, że wzorzec jest zapisany w pełnym formacie i odpowiednio ją wywołać.

Rotem
źródło
2
Zamiast przechowywać wzór w zmiennej, możesz użyć go re.compilew punkcie, w którym zdefiniujesz wzór, i przechowywać tylko wynikowy obiekt. W ten sposób flagi kompilacji wzorca (w tym re.VERBOSE) nie muszą być oddzielane od samego wzorca.
John Bartholomew
Naprawdę pomocna odpowiedź, dzięki! Ale jak mogę dopasować a, #jeśli używam pełnej flagi? Nawiasem mówiąc: linki źródłowe wydają się nie działać.
winklerrr
Okej, więc #można dopasować dosłownie w klasie znaków: [#](źródło: docs.python.org/3/library/re.html#re.X )
winklerrr
8

Zazwyczaj napiszę wyrażenie regularne i nie wyjaśnię poszczególnych elementów wyrażenia regularnego, ale raczej jego cel. To jest to, co i dlaczego. To trochę jak pytanie „jak powinny wyglądać moje komentarze?” na które można by powiedzieć: „ Nie pisz, co robi kod, napisz, dlaczego kod robi to, co robi

// 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, "");

O ile nie próbujesz nauczyć kogoś o wyrażeniach regularnych za pomocą komentarzy w kodzie, nie sądzę, aby wyjaśniać, co zrobi każdy pojedynczy fragment. Pracując z innymi programistami, możesz bezpiecznie założyć, że znasz coś jako globalne wyrażenia regularne.


źródło
3
byłbyś zaskoczony ...
Matt
6

Myślę, że to naprawdę zależy od tego, jak składasz regex razem. Ogólnie rzecz biorąc, myślę, że złym pomysłem byłoby umieszczanie komentarzy w samym łańcuchu wyrażeń regularnych (o ile wiem, nie jest to możliwe w większości scenariuszy). Jeśli naprawdę chcesz skomentować określone fragmenty wyrażenia regularnego (próbujesz kogoś nauczyć?), To podziel każdy fragment na osobne ciągi w swoich liniach i skomentuj każdą linię, używając normalnego procesu komentowania w języku programowania. W przeciwnym razie odpowiedź pleinolijf jest całkiem dobra.

przykład:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter
Matt
źródło
4

Zwykle definiuję stałą łańcucha, której nazwa opisuje ogólny cel wyrażenia regularnego.

Na przykład:

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

Możesz dodać komentarz powyżej tej stałej, aby podać jej opis, ale zwykle sama nazwa powinna wystarczyć.

Bernard
źródło
1
Jedną dodatkową rzeczą, która podoba mi się w tej odpowiedzi, jest to, że jeśli zostanie wykorzystana w więcej niż jednym miejscu, intencja musi być również realizowana - nie zapomnij jej skomentować.
J Trana
3

W niektórych scenariuszach deweloperzy mogą używać wyrażeń regularnych w celu dopasowania tekstu poza typową domeną. Pierwotni programiści mogli przejść wiele iteracji przechwytujących różne przypadki brzegowe, które mogły zostać odkryte tylko w tym procesie iteracyjnym. Zatem kolejni programiści mogą nie zdawać sobie sprawy z wielu przypadkowych przypadków, z którymi pierwotni programiści zajmowali się, nawet jeśli są świadomi ogólnego przypadku.

W takich przypadkach warto udokumentować przykłady zmian. Lokalizacja tej dokumentacji może się różnić w zależności od ilości (np. Niekoniecznie w kodzie).

Jednym ze sposobów podejścia jest założenie, że przyszli programiści będą mieli tylko podstawową wiedzę, na przykład, jak działają wyrażenia regularne, ale nie wiedzę, którą ty (1) posiadałeś przed opracowaniem wyrażeń regularnych, które niekoniecznie byłyby znane przyszli programiści lub (2) wiedza zdobyta podczas programowania (np. odkryte przypadki skrajne).

Na przykład, jeśli podczas programowania mówisz coś w stylu „Och, nie wiedziałem, że X może przyjąć tę formę”, warto to udokumentować (i być może część wyrażenia regularnego, która obsługuje tę odmianę).

bstovall
źródło
2

Komentarze powinny zawierać przydatne informacje, które nie są oczywiste z kodu.

  1. Ułatw zrozumienie tego, co wyrażenie ma robić na poziomie wymagań, w samym kodzie lub w komentarzu. Celem tego wyrażenia jest sprawdzenie poprawności adresów e-mail lub wybranie kanadyjskich numerów telefonów.
  2. Ułatw zrozumienie, co faktycznie robi wyrażenie, tj. Tego, co ocenia wyrażenie. Najpierw spróbuj to wyjaśnić, dzieląc wyrażenie, jeśli najpierw sprawdzisz wszystkie łączniki, a następnie usuniesz wszystkie liczby, a następnie sprawisz, że dwuczęściowe wyrażenie ze zmiennymi zawierającymi wartości pośrednie, znacznie ułatwi czytanie i czytelnik będzie w stanie przejść przez logikę krok po kroku. (Znana jest odpowiedź na pytanie na SE, w którym ktoś próbuje odszyfrować stary kod, który wymaga manipulacji bitami „>>” i dowiedzieć się, czy określone flagi są ustawione tam, gdzie odpowiedź określa nie tylko to, co naprawdę robi kod, ale także autor pytania powinien zająć się dekonstrukcją tego rodzaju kodu w przyszłości, co właśnie staram się opisać, ale mogę ”

Istnieje niewiele aplikacji, które potrzebują każdego ostatniego cyklu, jeśli dopasowujesz wzorce do ogromnych zestawów danych, być może istnieje lepszy sposób, a może nie, ale w większości przypadków dodatkowy czas wykonania nie jest tak duży.

I pamiętaj, że następną osobą, która natknie się na twój kod i naprawisz błąd, możesz być ty za sześć miesięcy i nie ma możliwości, abyś zapamiętał, co powinien zrobić.

Encaitar
źródło
1

Wyodrębnij RegEx do osobnej klasy do znaczącej nazwy. Następnie udokumentowałbym kod za pomocą automatycznych testów.

To zapewni

  • Że kod faktycznie działa - także w przypadku narożników
  • Zapewnia, że ​​szybka „poprawka” nie psuje wielu skrzynek narożnych
  • Może dokumentować optymalizacje, w których wyłączanie cofania jest wyłączone

Oczywiście twoja klasa może obsługiwać kilka wyrażeń regularnych.

Carlo V. Dango
źródło