Forum: PC-Programmierung RegEx in Javascript zum Formatieren von Code-Kommentaren


von Fragesteller (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe gerade begonnen mich mit Java-Script zu beschäftigen. Dazu habe 
ich versucht eine einfache Syntax-Highlighting Funktion für eine HTML zu 
schreiben. Jetzt habe ich in meinem Script ein Problem mit der 
Formatierung von Kommentaren festgestellt (siehe Beispiel).
Wenn ich Schlüsselwörter in den Kommentartexten verwende werden diese 
auch als Schlüsselwörter formatiert. Ich hätte allerdings gerne wenn 
diese in den Kommentaren ignoriert würden.

Die Schlüsselwörter habe ich mit folgender Anweisung formatiert:
1
content= content.replace(/\b(return)\b/g, '<span class="syntax-cmd">$&</span>');

Die Schlüsselwörter habe ich mit folgender Anweisung formatiert:
1
content = content.replace(/\/\*/g, '<span class="syntax-com">\/*');
2
content = content.replace(/\*\//g, '*\/</span>')

Ich müsste jetzt entweder das Wort 'return' innerhalb des Kommentars 
ignorieren oder erkennen, dass das Wort 'return' innerhalb eines 
Kommentars steht. Kann das irgendwie direkt mit RegEx gelöst werden?

Gruß
Michael

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

Genau sowas ist das grundsätzliche Problem, wenn man Sprachen mit 
Regular-Expressions parsed.
Ich sage nicht, dass es nicht geht. Man kommt recht weit, wenn man 
anfängt, solche Ausnahmeregeln einzubauen. Direkt in der Regex würde ich 
eher nicht versuchen, die werden irgendwann bis zur Unleserlichkeit 
kompliziert.

Der theoretisch "richtigere" Weg wäre ein Parser mit einer 
HTML-Grammatik. Der könnte dir dann sagen, das ist ein Kommentar, das 
ein Schlüsselwort etc.

Theoretisch sage ich absichtlich: richtig ist er, weil man damit das 
Problem vollständig erschlagen kann. ABER so ein Parser fügt deinem Code 
auch einen ordentlichen Sockel an Komplexität hinzu.
Es ist gut möglich, dass die Regex-Lösung (+ einige Ausnahmeregeln) für 
dich reicht.

von Programmierer (Gast)


Lesenswert?

Tilo R. schrieb:
> Ich sage nicht, dass es nicht geht.

Nein, es ist unmöglich, kontextfreie Sprachen (das sind die meisten 
Programmiersprachen inkl. JS oder HTML) mit regulären Ausdrücken zu 
parsen. Wenn du eine RegEx-Bibliothek hast die das kann, ist das kein 
echter regulärer Ausdruck mehr. Beweis: Reguläre Ausdrücke können mit 
endlichen Automaten implementiert werden, welche nur endlich viel 
Speicher haben, mit welchem sich nicht abspeichern lässt, wie viele 
öffnende Klammern bisher gekommen sind (kontextfreie Sprachen erlauben 
konzeptuell beliebig viele), was man aber können muss, um die 
schließenden Klammern korrekt zu zählen.

Zum "richtigen" Parsen braucht es die Grammatik, einen Tokenizer und 
einen Parser für kontextfreie Grammatiken, z.B. einen 
nichtdeterministischen Kellerautomaten. Das ist alles nicht ganz 
trivial, lernt man im Informatik Studium. Für die Einarbeitung in die 
Programmierung ist das etwas zu viel.

von nfet (Gast)


Lesenswert?

Prüf doch einfach als erstes auf Kommentar und ignoriere das dann eben.
Also mach nach deinen Kommentar regex einfach ein return und ignoriere 
die Zeilen?

von PCRE tinkerer (Gast)


Lesenswert?

Ich nutze gern und viel PCRE ( grep -P ... ), weiss nun nicht was 
JS-RegEs alles umfasst...

Ein Bastelversuch könnte darin bestehen, alles zwischen "/*" und "*/" zu 
ignorieren.
Wehe aber wenn auch nur eine dieser 2 Sequenzen in einem Stringliteral 
auftaucht...
Von mehrzeiligen Kommentare haben wir gar noch nicht gesprochen.
Ditto auch für Schlüsselwörter in Stringliterale.

Die von Thilo und Programmierer eingebrachten Äusserungen treffen auf 
jeden Fall zu.

Die "Bemalung" von vorhandenem Code soll ja nur auf tatsächlichem Code 
angewendet werden.
Also könnte ein mehrstufiges Vorgehen darin bestehen, erstmal allen 
Nicht-Code zu identifizieren (Kommentar, Stringliterale, ...??) und wie 
auch immer auszublenden, bevor die "Codebemalung" ran darf.
Die Nicht-Code Teile gehören danach aber wieder an ihre ursprünglichen 
Stellein eingesetzt...

von Fragesteller (Gast)


Lesenswert?

Hallo,

vielen Dank für die schnellen Antworten. Es ist wohl nicht der beste weg 
dieses Problem über RegEx zu lösen. Ich werde mich damit noch ein 
Weilchen beschäftigen und versuchen das Problem mit Java-Script zu 
lösen. Ich will mich damit ja ohnehin etwas mehr beschäftigen.

Vielen Dank
Michael

von Tilo R. (joey5337) Benutzerseite


Lesenswert?

@Programmierer:
wir stehen auf der selben Seite! Was du schreibst ist mir alles klar und 
du hast meine Zustimmung.
Deswegen wollte ich dem TO sagen, wie es richtig geht.
Gleichzeitig wollte ich ihn aber nicht entmutigen, weil ich weiß, dass 
man mit Regexes (+ Zusatzlogik) recht weit kommen kann.


Dazu ein lustiger Schwank aus meinem früheren Entwicklerdasein:

Ich war mal in einem Projekt, da musste im Wesentlichen HTML geparsed 
werden, um dann ein paar Spezialelemente durch personalisierte Daten zu 
ersetzen (Herr/Frau, Vorname, Nachname, vorbereitete Kontent-Blöcke).

Mein erster Vorschlag war, dafür eine Template-Engine zu nehmen. Das 
wurde abgelehnt. Ich kam später in das Projekt "und sie hatten da schon 
was", das sie auch weiter für die Personalisierung von E-Mails verwenden 
wollten. Meine Aufgabe war es, etwas ähnliches fürs Web zu bauen (Idee: 
personalisierte Landing Pages und Formulare).

Also habe ich mir den E-Mail-Code angeschaut und eine 
Regex-Replace-Hölle mit Ausnahmeregeln gefunden.

Wenig begeistert schlug ich einen richtigen Parser mit Grammatik vor. 
Beim E-Mail-Versand hätte das zusätzlich den Vorteil gehabt, dass man 
den geparsten AST aufbewahren kann. Für jede neue personalisierte Mail 
muss dann nur einmal der AST traversiert werden, anstelle bei jeder 
neuen Mail ein halbes dutzend mal mit Regexes drüberlaufen zu müssen.
Das wurde auch abgelehnt, weil der Entwickler der Regex-Lösung eine Art 
Guru-Status hatte. Aber immerhin verstand ich langsam, warum man eine 
fast dreistellige Anzahl an Servern für den Mailversand brauchte...

Nach langem Hin und Her durfte ich es wenigstens in meinem Teil richtig 
machen. Als Parser habe ich ANTLR ausgewählt und ich weiß daher aus 
Erfahrung, dass das etliche Tage dauern kann, wenn man es das erste mal 
macht. Selbst wenn man ein anständiger Programmierer ist und die Worte 
Grammatik und kontextfrei schon mal gehört hat.

Im Ergebnis haben beide Lösungen funktioniert.
Änderungen an meinem Code, z.B. ein neues Element hinzufügen, musste ich 
allerdings selber machen, weil der Code "so kompliziert" war.
Aber eigentlich war es einfach: 1. Grammatik anpassen, so dass für das 
neue Knotenelement eine neue Klasse instantiiert wird. 2. Neue 
Knotenklasse mit zusätzlicher Funktionalität schreiben.

Auf der anderen Seite war das schwieriger. Die ganze Parserei war in 
einem File, das mit jedem neuen Element größer wurde. Und dann gab es 
darin einen (für mich unverständlichen) Wust an Bedingungen und 
Sonderregeln, die bei jedem neuen Element teilweise angepasst oder 
repliziert werden mussten.
Und dann gab es immer wieder unerwartete Einschränkungen: z.B. waren 
Anführungszeichen und spitze Klammern in einzeiligen Kommentaren 
abgefangen, spitze Klammern in einem Attributwert dagegen nicht.

Aber letztlich konnte man damit trotzdem arbeiten. Sowas macht man dann 
halt nicht, mit der Zeit lernt man die Eigenheiten des Systems kennen.

Und auch auf meiner Seite will ich nicht verschweigen, dass es bei 
ungültigen (d.h. nicht der Grammatik entsprechenden) Eingabedaten gar 
nicht so leicht ist, eine Fehlermeldung mit hilfreicher Angabe zur 
Problemstelle zu geben.

: Bearbeitet durch User
von FLEXibler BISON (Gast)


Lesenswert?

Fragesteller schrieb:
> Ich werde mich damit noch ein
> Weilchen beschäftigen und versuchen das Problem mit Java-Script zu
> lösen.

https://nearley.js.org/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.