Forum: PC-Programmierung vb.net: RegEx funktioniert nicht wie gewollt


von mined (Gast)


Lesenswert?

Guten Abend,

ich versuche hier mit VB.net aus mehreren große Textdateien 
rauszufiltern, was ich benötige.

In den Dateien befinden sich alle möglichen Buchstaben, Zahlen, 
Sonderzeichen...

für mich relevant ist alles, was mit 02 A1 beginnt, und mit 03 endet.
Allerdings nur, wenn 14 Zeichen ohne Leerzeichen, und 22 Zeichen mit 
Leerzeichen zwischen "02 A1" und "03" sind. -> Das filtert 
unvollständige Einträge heraus.

Die Textdateien sehen wie folgt aus (Beispiel-Ausschnitt):
1
001697: 2022-01-14 14:03:42,1513956 +0,0000023
2
3
4
 02 A1 03 02 A1 03 02 A1 03 02 A1 03 02 A1 03 02
5
 A1 71 F0 FF FF 00 92 AA 03 02 A1 03 02 A1 03 02
6
 A1 03

Aus diesem Auszug würde ich nun also
1
02 A1 71 F0 FF FF 00 92 AA 03
 erhalten wollen.

Mein RegEx Code sieht so aus:
1
 Dim sourcestring As String = ""
2
        Try
3
            Using textReader As New System.IO.StreamReader("pfad-zur-txt")
4
                sourcestring = textReader.ReadToEnd
5
            End Using
6
        Catch ex As Exception
7
            MsgBox(ex.Message)
8
        End Try
9
10
        Dim re As Regex = New Regex("02 A1 (.{18,22}?) 03", RegexOptions.Multiline Or RegexOptions.Singleline)
11
        Dim mc As MatchCollection = re.Matches(sourcestring)
12
        Dim mIdx As Integer = 0
13
        For Each m As Match In mc
14
                gefiltert.Text &= m.value
15
                mIdx += 1
16
        Next

Nun das Problem:

Aus mir unerklärlichem Grund wird in der gefiltert.Textbox auch
1
02 A1 03 02 A1 03 02 A1 03

angezeigt! In dachte, dass in meinem RegEx Pattern ganz klar steht, 
alles zwischen 02 A1 und 03 NUR matchenm wenn mindestens 18 Zeichen 
("(.{18,22}?)") - warum also wird 02 A1 03 gemachted?

So, wenn ich nun
1
RegexOptions.Multiline Or RegexOptions.Singleline
 zu NUR Multiline ändere, hab ich das Problem nicht mehr! Dann 
funktioniert es, wie es soll.

Dann allerdings (ohne SingeLine) wird bei folgendem Text nicht 
gematched:
1
02 A1 71 F0 FF FF 00
2
 94 00 03

Warum? Keine Ahnung...

Kann mir hier jemand auf die Sprünge helfen und auch erklären was ich 
falsch mache?

Danke schon im Voraus

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

mined schrieb:
> 02 A1 71 F0 FF FF 00
>  94 00 03

Ist das nur ein copy/paste Fehler oder hast du wirklich Zeilenumbrüche 
mitten in deinen Daten?

mined schrieb:
> Dann allerdings (ohne SingeLine) wird bei folgendem Text nicht
> gematched:
Das wäre ja auch richtig. Mit multiline wird die Regex für jede Zeile 
einzeln angewendet und nicht mehr Zeilenübergreifend. Bei singleline 
hast du einen einzigen Bandwurm der auch die Steuerzeichen für den 
Umbruch noch enthält.

Probiere mal "(02 A1 )([0-9A-Z \n]{18,22})( 03)" ob das so funktioniert 
wie du willst?

Zum Rumprobieren:
- https://regex101.com/r/WncbAT/2

Ich würde allerdings hergehen und vor dem Ausführen der Regex erstmal so 
Sachen wie Zeilenumbrüche an "falschen" Stellen erstmal mit einem 
replace entfernen, damit du nur noch einen langen Bandwurm hast.

von Heinz B. (Firma: Privat) (hbrill)


Lesenswert?

mined schrieb:
> Allerdings nur, wenn 14 Zeichen ohne Leerzeichen, und 22 Zeichen mit
> Leerzeichen zwischen "02 A1" und "03" sind. -> Das filtert
> unvollständige Einträge heraus.

Irgend W. schrieb:
> Probiere mal "(02 A1 )([0-9A-Z \n]{18,22})( 03)" ob das so funktioniert
> wie du willst?

Das würde ich auch zuerst zu einem Bandwurm machen.
Und noch an die Alternative denken, wenn der Bandwurm keine Leerzeichen
enthält. Ansonsten funktioniert das, was Irgend W. geschrieben hat.

von DerEinzigeBernd (Gast)


Lesenswert?

mined schrieb:
> Die Textdateien sehen wie folgt aus (Beispiel-Ausschnitt):

Zeig' mal mehr als nur einen Datensatz. Sind das tatsächlich mehrere 
Zeilen pro Datensatz?

von mined (Gast)


Lesenswert?

Erstmal Danke für eure Ideen ;)

Irgend W. schrieb:
> Ist das nur ein copy/paste Fehler oder hast du wirklich Zeilenumbrüche
> mitten in deinen Daten?

Ja, da sind wirklich Zeilenumbrüche an diversen Stellen, die Textfiles 
sind zu groß um das "manuell" zu korrigieren, ich hoffte daher, dass das 
mit RegEx klappt.

Irgend W. schrieb:
> Ich würde allerdings hergehen und vor dem Ausführen der Regex erstmal so
> Sachen wie Zeilenumbrüche an "falschen" Stellen erstmal mit einem
> replace entfernen, damit du nur noch einen langen Bandwurm hast.

Das habe ich nun gemacht. Keine Zeilenumbrüche und keine Spaces mehr.

Irgend W. schrieb:
> Probiere mal "(02 A1 )([0-9A-Z \n]{18,22})( 03)"

hier hab ich noch entsprechend die Leerzeichen (02A1) und (03) entfernt.
Allerdings werden nun schon wieder
1
02A10302A10302A103
 gematched...

ich hab auch
1
{20}
 statt
1
{18,22}
 probiert, klappt auch nicht. Egal ob RegEx Options SingleLine, 
Multiline, oder gar nichts.

Es wäre mir neu, dass bei "02A103" 20 Zeichen dazwischen sind...und nur 
dann soll er ja matchen, also muss irgendein Fehler in meinem Pattern 
sein.


Hier nochmal der Probe-Datensatz, mit dem ich das aktuell versuche:
1
Û–..........001765:2022-01 1414:03:42,2957730+0,02A10302A10302A10302A103000002602A171F0FFFF00DD960302A10302A10302A10302A10302A10302A173F1FEFD01EA860302A10302A10302A103002A10302A10302A1030


Vielleicht kann mir nochmal jemand auf die Sprünge helfen


Schönen Sonntag

von Retrofan (Gast)


Lesenswert?

Es sollten ja 7 Hexzahlen zwischen 02A1 und 03 sein.
Also sind es 14 Ziffern dazwischen. Damit du dann die
'03' nur dann mitangelst, wenn dazwischen 14 Ziffern stehen,
schlage ich folgendes Konstrukt vor :
1
(02A1)[0-9A-Z]{14}(03)

Diese beiden habe ich jetzt raus geangelt :
1
02A171F0FFFF00DD9603
2
02A173F1FEFD01EA8603

von mined (Gast)


Lesenswert?

Danke für eure Hilfe!

Ich hatte nun noch das Problem, dass
1
02A103EEFFFFF702A103
auch gematched wird.

Daher ist mein Pattern nun:
1
02A1(?:(?!03|02A1)[0-9A-Z]){14}03

Damit funktioniert - auf den ersten Blick - alles wie es soll.

von DerEinzigeBernd (Gast)


Lesenswert?

mined schrieb:
> Hier nochmal der Probe-Datensatz, mit dem ich das aktuell versuche:

Warum sieht der jetzt ganz anders aus als der im Eröffnungsposting?

von mined (Gast)


Lesenswert?

DerEinzigeBernd schrieb:
> Warum sieht der jetzt ganz anders aus als der im Eröffnungsposting?

wie es mir geraten wurde, hab ich Leerzeichen und Zeilenumbrüche 
entfernt.

von fop (Gast)


Lesenswert?

Du solltest vielleicht nicht alle Leerzeichen entfernen, damit man 
oberes von unterem Nibble unterscheiden kann. Ersetze einfach
1
[ \r\n]+
durch ein Leerzeichen.

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.