Reguläre Ausdrücke kommentieren

11

Gibt es gängige Methoden zum Kommentieren der regulären Ausdrücke: Inline-Kommentare, die auf einen anderen Teil von RegEx verweisen, oder allgemeine Kommentare für alle Ausdrücke?

m0nhawk
quelle
2
Es gibt aber Sie müssen genauer sein. Zum Beispiel unterstützt Bash Inline-Kommentare und Python bietet ausführliche reguläre Ausdrücke.
Sakisk
6
Meine Faustregel für reguläre Ausdrücke lautet: Wenn Sie den regulären Ausdruck kommentieren müssen, ist er zu kompliziert.
zzzzBov
1
Und fügen
Sie
Ich stimme nicht unbedingt zu, dass es zu kompliziert ist, wenn Sie es kommentieren müssen. Eine komplizierte Regex kann Ihnen immer noch Tonnen von zwingendem Code ersparen. Verwenden Sie einen guten beschreibenden Variablennamen, um den regulären Ausdruck zuzuweisen. Wenn es immer noch nicht klar genug ist, verwenden Sie einen kurzen Kommentar, um die ursprüngliche Absicht hinter dem regulären Ausdruck zu vermitteln .
Craig

Antworten:

10

Meiner Ansicht nach ist es eine gute Praxis, in Kommentaren genau anzugeben, was die allgemeine Idee des regulären Ausdrucks ist. Dies erspart anderen Entwicklern (oder manchmal Ihnen selbst) den Aufwand, den regulären Ausdruck in einen Parser wie RegExr einzufügen , nur um zu verstehen, was er tut.

pleinolijf
quelle
2
RegExr wird sowieso passieren, es sei denn, der Entwickler ist ein Regex-Savant. Ich stimme jedoch einer allgemeinen Beschreibung zu. Das mache ich mit meinen Regexen.
Robert Harvey
3
+1: Alles, was detaillierter ist, wird als Kommentar zu einem Crashkurs in Regex.
Matt
Diese Antwort und die Kommentare von @zzzzBov sind sinnvoll.
m0nhawk
1
Dies erspart nicht nur die mühsame Prüfung des regulären Ausdrucks, um ihn zu verstehen, sondern macht auch die Absicht des ursprünglichen Programmierers deutlich, insbesondere angesichts der eindeutigen Möglichkeit, dass der ursprüngliche Programmierer den regulären Ausdruck selbst zum ersten Mal falsch verstanden hat. In vielen Fällen kann die Zuordnung des regulären Ausdrucks zu einem guten Variablennamen jedoch einen großen Beitrag zur Bereitstellung einer angemessenen Dokumentation der Absicht leisten.
Craig
9

Dies ist eine sprachspezifische Antwort, aber in der Frage wird keine Sprache angegeben.

Das Buch "Dive Into Python" schlägt vor, Kommentare mithilfe von ausführlichen regulären Ausdrücken zu implementieren :

Mit Python können Sie dies mit so genannten ausführlichen regulären Ausdrücken tun. Ein ausführlicher regulärer Ausdruck unterscheidet sich in zweierlei Hinsicht von einem kompakten regulären Ausdruck:

  • Leerzeichen werden ignoriert. Leerzeichen, Tabulatoren und Wagenrückläufe werden nicht als Leerzeichen, Tabulatoren und Wagenrückläufe abgeglichen. Sie sind überhaupt nicht abgestimmt. (Wenn Sie einem Leerzeichen in einem ausführlichen regulären Ausdruck entsprechen möchten, müssen Sie ihn durch einen umgekehrten Schrägstrich umgehen.)
  • Kommentare werden ignoriert. Ein Kommentar in einem ausführlichen regulären Ausdruck ist wie ein Kommentar in Python-Code: Er beginnt mit einem #Zeichen und reicht bis zum Ende der Zeile. In diesem Fall handelt es sich um einen Kommentar in einer mehrzeiligen Zeichenfolge anstelle Ihres Quellcodes, der jedoch auf die gleiche Weise funktioniert.

Beispiel:

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

Quelle und weitere Details hier

Diese Methode hat den kleinen Nachteil, dass der Aufrufer wissen muss, dass das Muster in einem ausführlichen Format geschrieben ist, und es entsprechend aufrufen muss.

Rotem
quelle
2
Anstatt das Muster in einer Variablen zu speichern, können Sie es re.compilean der Stelle verwenden, an der Sie Ihr Muster definieren, und nur das resultierende Objekt speichern. Auf diese Weise müssen die Musterkompilierungsflags (einschließlich re.VERBOSE) nicht vom Muster selbst getrennt werden.
John Bartholomew
Wirklich hilfreiche Antwort, danke! Aber wie kann ich mit a übereinstimmen, #wenn ich das ausführliche Flag verwende? Übrigens: Die Quelllinks scheinen ausgefallen zu sein.
Winklerrr
Okay, #kann also buchstäblich innerhalb einer Zeichenklasse abgeglichen werden: [#](Quelle: docs.python.org/3/library/re.html#re.X )
winklerrr
8

Normalerweise schreibe ich einen regulären Ausdruck und erkläre nicht die einzelnen Teile des regulären Ausdrucks, sondern dessen Zweck. Das ist was und warum. Dies ist ein bisschen wie die Frage "Wie sollen meine Kommentare aussehen?" zu dem man sagen würde " Schreiben Sie nicht, was der Code tut, schreiben Sie, warum der Code tut, was er tut "

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

Wenn Sie nicht versuchen, jemandem über Kommentare im Code etwas über Regexes beizubringen, kann ich nicht erklären, was jedes einzelne Stück tun wird. Wenn Sie mit anderen Programmierern arbeiten, können Sie davon ausgehen, dass man etwas als globale reguläre Ausdrücke kennt.


quelle
3
Sie wären überrascht ...
Matt
6

Ich denke, es hängt wirklich davon ab, wie Sie den regulären Ausdruck zusammensetzen. Im Allgemeinen halte ich es für eine schlechte Idee, Kommentare in die eigentliche Regex-Zeichenfolge selbst einzufügen (soweit ich weiß, in den meisten Szenarien nicht möglich). Wenn Sie wirklich bestimmte Teile eines regulären Ausdrucks kommentieren müssen (versuchen Sie, jemanden zu unterrichten?), Teilen Sie jeden Block in separate Zeichenfolgen in eigenen Zeilen auf und kommentieren Sie jede Zeile mit dem normalen Kommentierungsprozess für Ihre Programmiersprache. Ansonsten ist die Antwort von pleinolijf ziemlich gut.

Beispiel:

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

Normalerweise definiere ich eine Zeichenfolgenkonstante, deren Name den Gesamtzweck des regulären Ausdrucks beschreibt.

Beispielsweise:

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

Sie können einen Kommentar über dieser Konstante hinzufügen, um eine Beschreibung zu erhalten, aber normalerweise sollte der Name der Konstante selbst ausreichen.

Bernard
quelle
1
Eine zusätzliche Sache , die ich gerne über diese Antwort ist , dass , wenn sie in mehr als einer Stelle verwendet wird, die Absicht hat getragen werden um zu - kein Vergessen , es zu kommentieren.
J Trana
3

In einigen Szenarien verwenden die Entwickler möglicherweise reguläre Ausdrücke, um Text außerhalb ihrer typischen Domäne abzugleichen. Die ursprünglichen Entwickler haben möglicherweise viele Iterationen durchlaufen, um verschiedene Randfälle zu erfassen, die möglicherweise nur durch diesen iterativen Prozess entdeckt wurden. Daher sind nachfolgenden Entwicklern möglicherweise nicht viele der Randfälle bekannt, mit denen sich die ursprünglichen Entwickler befasst haben, selbst wenn sie den allgemeinen Fall kennen.

In solchen Fällen kann es sinnvoll sein, Beispiele für die Variationen zu dokumentieren. Der Speicherort dieser Dokumentation kann je nach Menge variieren (z. B. nicht unbedingt im Code).

Eine Möglichkeit, dies zu erreichen, besteht darin, davon auszugehen, dass zukünftige Entwickler nur über Grundkenntnisse wie die Funktionsweise regulärer Ausdrücke verfügen, jedoch nicht über Kenntnisse, die Sie (1) vor der Entwicklung der regulären Ausdrücke hatten, die dem nicht unbedingt bekannt wären zukünftige Entwickler oder (2) Kenntnisse, die Sie während der Entwicklung erworben haben (z. B. entdeckte Randfälle).

Wenn Sie beispielsweise während der Entwicklung etwas wie "Oh, ich wusste nicht, dass X diese Form annehmen kann" sagen, lohnt es sich, dies zu dokumentieren (und möglicherweise den Teil des regulären Ausdrucks, der diese Variation behandelt).

bstovall
quelle
2

Kommentare sollten nützliche Informationen hinzufügen, die aus dem Code nicht ersichtlich sind.

  1. Machen Sie es einfach zu verstehen, was der Ausdruck auf Anforderungsebene tun soll, entweder im Code selbst oder in einem Kommentar. Hinter dem Ausdruck steht die Absicht, E-Mail-Adressen zu validieren oder kanadische Telefonnummern auszuwählen.
  2. Machen Sie es einfach zu verstehen, was der Ausdruck tatsächlich tut, dh was der Ausdruck ergibt. Versuchen Sie zunächst, dies durch Aufteilen des Ausdrucks zu verdeutlichen. Wenn Sie zuerst nach allen Bindestrichen suchen und dann alle Zahlen entfernen und dann einen zweiteiligen Ausdruck mit Variablen erstellen, die die Zwischenwerte enthalten, wird das Lesen erheblich erleichtert und der Leser wird es in der Lage, Schritt für Schritt durch Ihre Logik zu gehen. (Es gibt eine berühmte Antwort auf eine Frage zu SE, bei der jemand versucht, einen alten Code zu entschlüsseln, der eine Bitmanipulation '>>' beinhaltet und herausfindet, ob bestimmte Flags gesetzt sind, in denen die Antwort nicht nur beschreibt, was der Code wirklich tut, sondern wie Der Autor der Frage sollte sich in Zukunft darum kümmern, diese Art von Code zu dekonstruieren. Genau das versuche ich zu beschreiben, aber ich kann es. '

Es gibt nur wenige Anwendungen, die jeden letzten Zyklus benötigen. Wenn Sie massive Datensätze mit Mustern abgleichen, gibt es vielleicht einen besseren Weg, vielleicht auch nicht, aber für die meisten Dinge ist die zusätzliche Ausführungszeit keine so große Sache.

Und denken Sie daran, dass die nächste Person, die auf Ihren Code stößt und einen Fehler behebt, Sie in sechs Monaten sein könnte, und Sie werden sich auf keinen Fall daran erinnern können, was er tun sollte.

Encaitar
quelle
1

Extrahieren Sie die RegEx in eine separate Klasse in eine mit einem aussagekräftigen Namen. Dann würde ich den Code mit automatisierten Tests dokumentieren.

Dies wird sicherstellen

  • Dass der Code tatsächlich funktioniert - auch für Eckfälle
  • Stellt sicher, dass ein schneller "Bugfix" nicht viele Eckfälle vermasselt
  • Kann Optimierungen dokumentieren, bei denen das Backtracking deaktiviert ist

Natürlich kann Ihre Klasse mehrere reguläre Ausdrücke enthalten.

Carlo V. Dango
quelle