PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : .Net: regex gesucht


Elemental
2009-01-24, 21:27:18
Hallo zusammen,
ich versuche gerade mit einem Programm die Anworten eines ftp servers zu parsen. Klappt soweit auch alles ganz gut, nur Dateien die über links irgendwohin ausgelagert wurden machen mir noch Probleme, da ich dafür keinen passenden Regex habe.

Für normale "Eintrage" wie z.B.
"drwxr-xr-x 2 root root 1024 Jan 24 12:32 BeyondDreams-UFS-910-MOD"

wird folgender regex verwendet

"(?<dir>[\\-d])(?<permission>([\\-r][\\-w][\\-xs]){3})\\s+\\d+\\s+\\w+\\s+\\w+\\s+(?<size>\\d+)\\s+(?<timestamp>\\w+\\s+\\d+\\s+\\d{1,2}:\\d{2})\\s+(?<name>.+)",


Ich bräuchte jetzt einen regex für sowas

"lrwxrwxrwx 1 root root 33 Aug 15 1907 bouquets.radio -> /var/swap/Settings/bouquets.radio"


Ich bin nicht besonders fit mit den regular expressions und versuche mich bisher vergeblich daran.
Kann mir hier vielleicht jemand weiterhelfen?

mfG
Elemental

Monger
2009-01-25, 23:01:29
Nachdem ich mir das Ding jetzt mal eine Weile durch den Kopf gehen ließ... eigentlich passt nur vorne die "dir" Gruppe nicht, oder?

Wechsel doch das "(?<dir>[\\-d])" gegen ein "(?<dir>[\\-d])" aus.

Das zweite was ich sehe, ist dass der Timestamp im zweiten Fall keinen Doppelpunkt hat. Oder ist das ein Tippfehler deinerseits? Dann musst du noch den Doppelpunkt hinten in der timestamp Gruppe rausnehmen, oder zumindest optional machen.

Das müsste es dann eigentlich gewesen sein.

Elemental
2009-01-26, 13:21:40
...
Wechsel doch das "(?<dir>[\\-d])" gegen ein "(?<dir>[\\-d])" aus.
...


Ähm, ich sehe irgendwie keinen Unterschied. :confused:

...
Das zweite was ich sehe, ist dass der Timestamp im zweiten Fall keinen Doppelpunkt hat. Oder ist das ein Tippfehler deinerseits? Dann musst du noch den Doppelpunkt hinten in der timestamp Gruppe rausnehmen, oder zumindest optional machen.
...

Eigentlich kann es kein Tippfehler sein, da ich das direkt aus Visual Studio copy&pasted habe. Vielleicht ist das ja wirklich das Problem, dass bei links kein : im timestamp ist.
Werd ich testen.

Schonmal danke! :smile:

Monger
2009-01-26, 20:53:14
Ich Dummkopf! :ugly:

Meine natürlich "(?<dir>[\\-l])" - immerhin steht bei dir im Beispielstring ein kleines "L".

Elemental
2009-01-27, 19:07:27
Oh, Tatsache :eek: Hab ich bisher auch immer übersehen, das kleine L

edit: Gerade getestet: Mit kleinem L und ohne den Doppelpunkt geht's.

Es gibt aber auch Links mit Doppelpunkt im timestamp, wie ich gerade gemerkt habe:

"lrwxrwxrwx 1 root root 18 Jan 24 12:32 blacklist -> /var/tmp/blacklist"


Wie krieg ichs denn hin, dass in "name" wirklich nur der Name steht und das Ziel des Links in z.B. "linktarget" ?

Monger
2009-01-27, 20:33:55
Wie du den Doppelpunkt optional machst ist dir klar, oder? Einfach ein Fragezeichen dahinter.

Du kannst den hinteren Teil natürlich präziser formulieren. Der Punkt in "(?<name>.+)" konsumiert nunmal jedes beliebige Zeichen (außer standardmäßig Zeilenumbruch afaik).

Eine Möglichkeit wäre

(?<name>\\w+)\\s->\\s(?<linktarget>[\\w/]+)

Ich hoffe, ich hab alles richtig escaped! :D

Elemental
2009-01-28, 12:13:30
Wie du den Doppelpunkt optional machst ist dir klar, oder? Einfach ein Fragezeichen dahinter.


Da ich ein Array mit mehrern möglichen Parse-Strings habe, die dann alle durchprobiert werden, hab ich einfach einen weiteren hinzugefügt, bei dem
"\\d{1,2}:\\d{2}" ersetzt ist durch "\\d{4}"


Du kannst den hinteren Teil natürlich präziser formulieren. Der Punkt in "(?<name>.+)" konsumiert nunmal jedes beliebige Zeichen (außer standardmäßig Zeilenumbruch afaik).

Eine Möglichkeit wäre

(?<name>\\w+)\\s->\\s(?<linktarget>[\\w/]+)

Ich hoffe, ich hab alles richtig escaped! :D

Danke! Probier ich heute Abend aus :smile:

Elemental
2009-01-28, 20:00:54
Ok, funktionieren tuts. Danke! :)
Aber wieso is eigentlich das \\w am Ende in eckigen Klammern?

Monger
2009-01-28, 20:07:23
Weil da noch ein Slash "/" hinten dran kommt. Und die beiden Zeichen müssen natürlich gruppiert werden.

Elemental
2009-01-30, 10:23:00
Und wieso nicht genauso wie beim Namen, also so:
(?<linktarget>\\w+)

Monger
2009-01-30, 10:50:09
Weil \\w nur Buchstaben und Ziffern umfasst - aber keine Sonderzeichen wie Slashes und Punkte.

Was mich darauf bringt, dass das mit dem Namen vorne überhaupt nicht stimmen kann. Da sind ja Punkte im Namen drin. Müsste also heißen:


(?<name>[\\w\\.]+)

Elemental
2009-01-30, 12:38:06
Weil \\w nur Buchstaben und Ziffern umfasst - aber keine Sonderzeichen wie Slashes und Punkte.

Alles klar, danke für die Erklärung! :)


Was mich darauf bringt, dass das mit dem Namen vorne überhaupt nicht stimmen kann. Da sind ja Punkte im Namen drin. Müsste also heißen:


(?<name>[\\w\\.]+)


Stimmt hast recht! Ich hatte bei meinen letzten "Schnelltests" nur mit der Zeile

"lrwxrwxrwx 1 root root 18 Jan 24 12:32 blacklist -> /var/tmp/blacklist"

geschaut ob auch geht.

Noch einfacher und auch funktionieren tuts mit:
(?<name>.+)

Monger
2009-01-30, 14:28:56
Noch einfacher und auch funktionieren tuts mit:
(?<name>.+)
In dem Fall funktioniert es, weil wir mit dem "->" zwischendrin ganz gut verhindern, dass es Mehrdeutigkeiten geben kann.

Aber in aller Regel ist ein "." eine schlechte Idee, weil du damit eben jede Art von Zeichen konsumierst.

Nehmen wir mal an, das Linktarget wäre optional. Dann könntest du ja auf die Idee kommen, folgenden Ausdruck für Name und Linktarget zu nehmen:

(?<name>.+)(?:\\s->\\s(?<linktarget>.+))?

Wenn du diesen Ausdruck ausprobierst, wirst du feststellen dass in linktarget nie was drin steht - weil ein Punkt nunmal jedes Zeichen konsumiert - inklusive Leerzeichen, Bindestrich, kleiner als und sonstige Sonderzeichen. Es bleibt fürs Linktarget also gar nix übrig. Und da das Linktarget optional ist, gibt es trotzdem einen gültigen Match.

Sowas kann einen wahnsinnig machen. Ich kann nur empfehlen, sich ein kleines Testtool zu schreiben was einem die Gruppen ausgibt, damit man mal fix einen regulären Ausdruck testen kann, und auch sieht wo welche Zeichen geblieben sind.

Elemental
2009-01-30, 15:06:05
Tja, die regular expressions können einen echt in den Wahnsinn treiben :D