![]() |
Regulärer Ausdruck - Unerwartetes Verhalten
Hallo,
Heute habe ich mal ein ganz anderes Problem. Wie vielleicht der ein oder andere weiß (oder auch nicht) kann man sich in Notepad++ eine Funktionsliste der gerade geöffneten Quelltextdatei anzeigen lassen. Das funktioniert standardmäßig allerdings nicht mit .pas Dateien. Nun gibt es bei Notepad++ eine XML Datei in der man für andere Sprachen reguläre Ausdrücke hinterlegen kann die den Anfang einer function/procedure erkennen. Erkannt werden sollen aber nur die wirklichen Implementierungen, nicht die Deklaration im interface-Teil, weswegen ich meine RegEx vom Prinzip her so aufgebaut habe. (Sie funktioniert auch soweit gut, aber dazu gleich mehr): 1) "procedure" oder "function" finden 2) Danach ein Bezeichner 3) Ggf. Klammern mit beliebig vielen "Parameter: Typ;" Vorkommen 4) Ggf. ": FunktionsResultTyp" 5) beliebig viele Modifier in der Form "Modifier;" 5.1) Leerzeichen/Zeilenumbrüche 6) "begin" oder "asm" oder "var"/"const" Der Algorithmus ist auf keinen Fall wasserdicht aber er reicht für meine Zwecke. Die RegEx dazu:
Code:
Das klappt wie gesagt ganz gut. Folgende einfache Unit (ich habe es mal aufs Minimum runtergeschraubt):
1) ((function|procedure)\b)
2) [\s]+[\w]+ 3) (\((([\s]*[\w]+[\s]*,?)*:[\s]*[\w]+;?)*\))? 4) ([\s]*:[\s]*[\w]*)?; 5) ([\s]*[\w]+;)* 5.1) [\s]*[\n]* 6) (begin|var|const|asm)\b
Delphi-Quellcode:
Dort wird natürlich letztendlich nichts gefunden weil das ja nur die interface-Definitionen der Prozeduren sind. Allerdings braucht Notepad++ und auch einige online RegEx Parser sehr sehr lange (10-20 Sekunden) für das parsen der Datei. Notepad++ hängt sich dabei fast auf.
unit cga;
interface procedure pic_init(slaveIRQ: Byte; IRQStartIndex: Byte); procedure cga_setattr(color: Cardinal; flags: Byte); implementation end. Es scheint an der Zeile
Delphi-Quellcode:
procedure pic_init(slaveIRQ: Byte; IRQStartIndex: Byte);
zu hängen. Genauer: An den Parametern. Der Prozedurname kann so bleiben. Wenn ich der Prozedur die Parameter von cga_setattr gebe, dann dauert das parsen < 1 Sekunde. Habe auch große .pas Dateien mit 20+ Prozeduren inkl. interface Deklarationen die in < 1 Sekunde durchlaufen. Nur diese eine Prozedur macht aus irgendwelchen Gründen Probleme. Kann mir irgendjemand vielleicht helfen und sagen warum meine RegEx bei dieser Zeile so ins Stolpern kommt? (regexe.de meldet "Regulärer Ausdruck ist zu tief verschachtelt. Bitte vereinfachen Sie den Ausdruck.") |
AW: Regulärer Ausdruck - Unerwartetes Verhalten
Müssten nicht die ersten beiden Fragezeichen bei 3) hinter die Klammern? Denn der ganze Ausdruck in den Klammern soll doch optional sein, richtig? Das Fragezeichen macht immer den direkt davorstehenden Ausdruck/Zeichen/Klasse optional - so wie es da steht, also nur das Komma und das Semikolon.
Bzw. genaugenommen können die Fragezeichen komplett weg, denn der Stern macht es ja bereits optional, denn * findet kein oder mehr Vorkommen der/des davorstehenden Klasse/Zeichen/Gruppe. regexe.de ist ohne Fragezeichen jedenfalls zufrieden. MfG Dalai |
AW: Regulärer Ausdruck - Unerwartetes Verhalten
Zitat:
Sehr spannend, aber ich habe auch noch keine Idee. Wenn man den (begin|var|...)-Teil weglässt, funktioniert der Regex übrigens und findet die Deklarationen. |
AW: Regulärer Ausdruck - Unerwartetes Verhalten
Zitat:
Andere Möglichkeit: bei 3) die Sternchen nach den Klammern in Fragezeichen umwandeln, also so
Code:
Funktioniert auf regexe.de ohne zu tiefe Verschachtelung.
(\((([\s]*[\w]+[\s]*,?)?:[\s]*[\w]+;?)?\))?
MfG Dalai |
AW: Regulärer Ausdruck - Unerwartetes Verhalten
@Valle: Der begin/var Teil SOLL ja da sein. Es ist schon richtig dass er die Interface-Deklarationen nicht findet. Er soll nur die Implementierungen der Funktionen finden ;)
@Dalai: Die Sternchen brauche ich sonst können die proceduren nur einen Parameter haben und mehrere Parameter vom selben Typ kommagetrennt geht dann auch nicht mehr. Habe neue Informationen: 1. Umso mehr Großbuchstaben in den Parameterbezeichnungen enthalten sind desto länger dauert es :gruebel: 2. Wenn ich das erste [\s]* im Parameterausdruck weglasse (3) dann geht das ganze (auch mit Großbuchstaben ruckzuck. Natürlich findet er dann keine Funktionen mehr wo Leerzeichen vor dem Parameternamen sind. :gruebel: Ich sehe aber irgendwie nicht den Zusammenhang bzw. die Gründe dafür. Falls ihr Lust habt könnt ihr mit der RegEx auf regexe.de selbst mal rumspielen. Nochmal die gesamte RegEx in einem Stück:
Code:
((function|procedure)\b)[\s]+[\w]+(\((([\s]*[\w]+[\s]*,?)*:[\s]*[\w]+;?)*\))?([\s]*:[\s]*[\w]*)?;([\s]*[\w]+;)*[\s]*[\n]*(begin|var|const|asm)\b
|
AW: Regulärer Ausdruck - Unerwartetes Verhalten
Zitat:
War so eine Info wie dein 2. aus deinem letzten Post. ;-) Ich vermute mittlerweile irgendwie, dass du einen Bug in der entsprechenden Library gefunden hast. Hast du mal untersucht, inwiefern dieses Verhalten mit unterschiedlichen Platformen und Implementationen zusammenhängt? |
AW: Regulärer Ausdruck - Unerwartetes Verhalten
Mal ein bisschen vereinfacht:
Code:
Denn was innerhalb der Klammern nach dem Funktionsnamen steht, ist eigentlich egal. Warum das bei regexe.de allerdings auch auf den Deklarationsteil match, weiß ich nicht, bei
((function|procedure)\b)[\s]+[\w]+(\(.*\))?([\s]*:[\s]*[\w]*)?;([\s]*[\w]+;)*[\s]*[\n]*(begin|var|const|asm)\b
![]() [EDIT] regexe.de erfasst die Deklaration, wenn die Option "Punkt erfasst auch Umbrüche" aktiviert ist. Schaltet man diese aus, matcht die Seite dasselbe wie regexr.com [EDIT] MfG Dalai |
AW: Regulärer Ausdruck - Unerwartetes Verhalten
@Dalai: Deine RegEx funktioniert bei mir nicht gut aber ich habs etwas umgebaut und jetzt funktionierts super. Du hast Recht: Es interessiert eigentlich nicht was in der Klammer steht.
Aber ein "." ist scheinbar zu viel des Guten. Benutze statt dem . jetzt [\w\s:,;]* und damit scheints gut zu funktionieren. Das müssten ja soweit alle Zeichen sein die normalerweise auftauchen könnten oder? ansonsten wird das da noch hinzugefügt. Auf jeden Fall jetzt schonmal Danke an euch beide! :) Warum mein ursprünglicher Ausdruck so Probleme gemacht hat weiß ich zwar immer noch nicht so genau (vllt. ist es wirklich ein Fehler?) aber solange es jetzt klappt :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz