vb.net: RegEx funktioniert nicht wie gewollt

Gast #7316368
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

(Firma: egal) #7316445
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:

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.

(Firma: Privat) #7316770
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.

Gast #7317094
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

Gast #7317392
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
Gast #7317481
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren