Forum: PC-Programmierung Regex - "-" gut, "--" böse


von Martin S. (sirnails)


Lesenswert?

Hallo,

kurze Frage:

Ausgangsdatensatz:
VT_Float 32 Bit  --  Inductance (Henry)  --  read only  --  -3

Soll per Regex zu vier Gruppen werden:

VT_Float 32 Bit
Inductance (Henry)
read only
-3
1
([A-Za-z0-9\s\_\/\(\)]+)*

will nicht so recht. Er erkennt zwischen den Wörtern falsche Gruppen, 
das "-" vor der 3 wird ignoriert.

Testbar hier: https://regex101.com/

Wer kann mir kurz auf die Sprünge helfen? Hänge gerade irgendwie total.

Mahlzeit :-)

von sven (Gast)


Lesenswert?

Nimm doch string.Split("--")

von Datenlutscher (Gast)


Lesenswert?

Martin S. schrieb:

> Wer kann mir kurz auf die Sprünge helfen? Hänge gerade irgendwie total.
/(VT_Float 32 Bit)  --  (Inductance \(Henry\))  --  (read only)  -- 
(-3)/

von Martin S. (sirnails)


Lesenswert?

Datenlutscher schrieb:
> Martin S. schrieb:
>
>> Wer kann mir kurz auf die Sprünge helfen? Hänge gerade irgendwie total.
> /(VT_Float 32 Bit)  --  (Inductance \(Henry\))  --  (read only)  --
> (-3)/

Hahahaha...

Es gibt natürlich auch noch andere Datensätze. Oder warum sonst würde 
ich mir freiwillig Regex antun?!

von Simon B. (nomis)


Lesenswert?

Martin S. schrieb:
1
> Ausgangsdatensatz:
2
> VT_Float 32 Bit  --  Inductance (Henry)  --  read only  --  -3
3
> 
4
> Soll per Regex zu vier Gruppen werden:
5
> 
6
> VT_Float 32 Bit
7
> Inductance (Henry)
8
> read only
9
> -3

Die Lösung von Datenlutscher ist natürlich korrekt aber maximal 
unhilfreich  :)
1
> ([A-Za-z0-9\s\_\/\(\)]+)*

Ja, Regexes können schonmal komplex werden. Du suchst hier alle Gruppen, 
die aus einer möglichhst langen Aneinanderreihung von Buchstaben, 
Ziffern, Whitespace und einigen Sonderzeichen bestehen. Das "-" lässt Du 
aus, konsequenterweise wird es auch bei der -3 nicht als Wortbestandteil 
erkannt. Insofern ist schonmal klar, warum diese Regex nicht 
funktioniert.

Meine Lösung sieht so aus:
1
(([^-\s]|-[^-\s]|\s+[^-][^-])*)(\s*--\s*)?

Ich suche eine beliebig lange Abfolge von Zeichenketten die eine der 
drei folgenden Bedingungen erfüllt:
  - es ist ein Zeichen, welches weder ein Whitespace noch ein "-" ist
  - es ist ein "-" gefolgt von einem Zeichen welches weder ein 
Whitespace noch ein "-" ist
  - es ist eine mindestens ein Zeichen lange Folge von Whitespaces plus 
zwei weitere Zeichen, die beide kein "-" sein dürfen

Anschließend kann optional ein Separator folgen.

Für die Erkennung Deiner Tokens ist die 1. Gruppe dieses Regex-Ausdrucks 
relevant.

Übrigens gibt es auch in dieser etwas ausgebauten Regex noch 
corner-Cases bei denen man entscheiden muss ob sie den gewünschten 
Texten entsprechen (mindestens ein einsames "-" wird im Moment nicht 
erkannt).

Einiges der Komplexität in der Regex kommt daher, dass ich rund um den 
Separator beliebig viele Whitespaces erlauben wollte und die nicht in 
meinen Wunschtexten einbezogen haben wollte.

Prinzipiell muss man immer überlegen, ob Regex das Mittel der Wahl ist. 
Der Vorschlag mit dem "split" ist valide und sinnvoll und kann dem 
Problem eher angemessen sein.

Viele Grüße,
        Simon

: Bearbeitet durch User
von Datenlutscher (Gast)


Lesenswert?

Martin S. schrieb:
> Es gibt natürlich auch noch andere Datensätze. Oder warum sonst würde
> ich mir freiwillig Regex antun?!
Wenn du dir mal meine Antwort genau anschaust und mit deinem Versuch 
vergleichst kannst du dir den Rest selbst zusammenreimen was bei deinem 
Ausdruck fehlte.

Ein bisserl mitarbeiten bitte.

von Martin S. (sirnails)


Lesenswert?

Deine Lösung hat den Nachteil, dass sie pro echten Treffer drei Gruppen 
erzeugt und dafür jeweiles einen Full match. Das lässt sich in Labview 
so nicht verwenden, weil dort die Gruppen nur auf den ersten Match 
bezogen sind.

Gar nicht mal so leicht zu lösen :-)

von Erik (Gast)


Lesenswert?

([A-Za-z0-9\s\_\(\)]+)\s{2,}--\s{2,}([A-Za-z0-9\s\_\(\)]+)\s{2,}--\s{2,} 
([A-Za-z0-9\s\_\(\)]+)\s{2,}--\s{2,}([-0-9]+)

Nicht schön, aber funktioniert.

Group 1.  0-15  `VT_Float 32 Bit`
Group 2.  21-39  `Inductance (Henry)`
Group 3.  45-54  `read only`
Group 4.  60-62  `-3`

von MaWin (Gast)


Lesenswert?

Warum muss es Regex sein?
Kann es nicht viel einfacher konventionell geparst werden, per Suche 
nach "--"?

Wenn es denn unbedingt Regex sein muss: Sind es immer 4 Gruppen? Dann 
ist die Regex trivial.

von A. S. (Gast)


Lesenswert?

Martin, was uns fehlt ist doch die Bedingung, welche Kombinationen denn 
genau gefunden werden soll.

A) Sollen -- und NewLine die einzig erlaubten Trenner sein und alles 
andere wird gefunden?

B) Was ist mit Whitespaces vor und hinter Trennern? Was mit in den 
Gruppen?

C) Gibt es kein "Position after Match"?

D) Kannst Du Gruppen verwenden?

von Daniel F. (df311)


Lesenswert?

/((?:(.+?)\s*?--\s*)|(.+))/
sollte laut https://regex101.com/ passen

von MaWin (Gast)


Lesenswert?

Daniel F. schrieb:
> /((?:(.+?)\s*?--\s*)|(.+))/
> sollte laut https://regex101.com/ passen

nein?

von Daniel F. (df311)


Lesenswert?

MaWin schrieb:
> Daniel F. schrieb:
>> /((?:(.+?)\s*?--\s*)|(.+))/
>> sollte laut https://regex101.com/ passen
>
> nein?

ok, scheinbar ist da beim kopieren irgendwo was verloren gegangen.
tschuldign

aber im prinzip ist es eh wurscht, weil z.b. achims fragen nicht 
beantwortet sind

von Martin S. (sirnails)


Lesenswert?

Daniel F. schrieb:
> aber im prinzip ist es eh wurscht, weil z.b. achims fragen nicht
> beantwortet sind

Mit purer Absicht. War im Urlaub. Arbeit ist Arbeit, Urlaub ist Urlaub. 
Ich will keinen Herzinfarkt mit 57 :-)

von Erik (Gast)


Lesenswert?

Was spricht denn gegen meine Antwort oben?

von Martin S. (sirnails)


Lesenswert?

Achim S. schrieb:
> Martin, was uns fehlt ist doch die Bedingung, welche Kombinationen denn
> genau gefunden werden soll.
>
> A) Sollen -- und NewLine die einzig erlaubten Trenner sein und alles
> andere wird gefunden?

Ja. Die Anzahl der Gruppen ist fix (siehe Beispiel)

> B) Was ist mit Whitespaces vor und hinter Trennern? Was mit in den
> Gruppen?

Die gehören zu den Trennern dazu " -- ".

> C) Gibt es kein "Position after Match"?

Was genau meinst Du damit?

> D) Kannst Du Gruppen verwenden?

Ja.

von Martin S. (sirnails)


Lesenswert?

Erik schrieb:
> Was spricht denn gegen meine Antwort oben?

Your regular expression does not match the subject string.

von Erik (Gast)


Lesenswert?

Martin S. schrieb:
> Your regular expression does not match the subject string.

Das Board fügt Leerzeichen ein, wenn man es kopiert. Du musst aus beiden 
Zeilen schon eine machen...

Oder meist du ich denke mir die Match Information aus?

von Erik (Gast)


Lesenswert?

https://regex101.com/r/F5tjyr/1

damit das Löschen nicht zu schwer ist

von Martin S. (sirnails)


Lesenswert?

Erik schrieb:
> Martin S. schrieb:
>> Your regular expression does not match the subject string.
>
> Das Board fügt Leerzeichen ein, wenn man es kopiert. Du musst aus beiden
> Zeilen schon eine machen...

Es empfielt sich, solche Blöcke in [ CODE ]-Tags zu packen.

> Oder meist du ich denke mir die Match Information aus?

Nö, aber ein unglücklicher Zustand führte dazu, dass es keinen Match 
gab. Und nein, es liegt nicht daran, dass ich zu blöd zum kopieren bin.

von Erik (Gast)


Lesenswert?

Aha, und taugt die Regexp jetzt für dein Vorhaben?

von Martin S. (sirnails)


Lesenswert?

Erik schrieb:
> Aha, und taugt die Regexp jetzt für dein Vorhaben?

Ja, danke.

Mich würde interessehalber trotzdem noch eine möglichst elegante Lösung 
interessieren :-)

Look-aheads und look-behinds sind mir bisher aber noch nicht zugänglich 
geworden.

von fop (Gast)


Lesenswert?

1
^\s*((?<teilchen>.*?)\s*--\s*){3}(?<teilchen>.*?)\s*$

Wobei Du nur die mit teilchen benamten Gruppen haben möchtest. Die {3} 
musst Du gegen etwas anderes tauschen, wenn es nicht immer genau 4 
Datensätze pro Zeile sind.

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.