REGEX Wert zwischen zwei Zeichen prüfen?

4 Antworten

Von Experte FaTech bestätigt

Nun wie du das mit Regex löst wurde dir ja schon gesagt. Generell läuft hier aber denke ich sehr Vieles falsch.

Zum einen, dass die Daten in dieser Art überhaupt in einer Zelle stehen und du sie nachträglich auseinanderbauen musst. Eine relationale Datenbank ist eben dafür da, Daten atomar zu speichern und ggf. mit entsprechenden JOINs wieder zusammenzufügen.

Weiter eignet sich selbst wenn wir das ignorieren doch SQL selbst Bestens dafür und man kann einfach ein LIKE oder INSTR nutzen. Und genauso sind Funktionen in den Hochsprachen zum finden eines Strings hier angebrachter als ein Regex, der wohl rechenaufwendiger und komplizierter ist.

Also was spricht gegen ein:

SELECT TABELLE.Spalte FROM TABELLE
WHERE  TABELLE.DeinString LIKE '%|2|%';

Oder ein:

SELECT TABELLE.Spalte FROM TABELLE
WHERE  INSTR(TABELLE.DeinString, '|2|') != 0;

Aber wie gesagt, eigentlich stinkt das schon von den Tabelleninhalten her. Klar gibt es auch hier halbwegs brauchbare Mittel und Wege, wie textbasierte Indizes usw. die damit dann zumindest in Bezug auf Performance keine großen Nachteile bringen.

Woher ich das weiß:Berufserfahrung – Softwareentwickler/Projektleiter seit 2012
skyynet 
Fragesteller
 14.06.2022, 08:07

Danke. Irgendwie war ich aufgrund der Trennung mit Zeichen ('|') in der irrigen Annahme, mit RegEx arbeiten zu müssen. Dein Vorschlag mit %|2|% funktioniert aber gut und ich setze es so um.

Warum ich in einer Zelle mehrere Werte speichere? Ich habe in der db viele Infos zu Mobiltelefonen und für jedes Feature ein Feld. Bei den 2G/3G/4G/5G Bändern/Frequenzen stehen jedoch unterschiedlich viele. Wenn nun ein Nutzer nach den Frequenzen filtern will, die z.B. in seinem (Urlaubs-)Land genutzt werden, um zu sehen, ob sein (noch zu kaufendes) Smartphone diese unterstützt, nutze ich die Query. Bisher hatte ich vieles in PHP realisiert und mir mit MySQL dumm die ganze Tabelle eingelesen. Das war natürlich viel zu langsam. Das baue ich gerade um und Du hast mir dabei sehr geholfen.

0

\|2\|

Solange du nur einen Match willst klappt das super.

Nur kannst du eben nicht gleichzeitig mehrere Zahlen matchen, heißt bei |1|2|2|4| würdest du nur einen Match bekommen und sowas wie \|(2|3)\| wird nicht funktionieren.

Da helfen dann Lookaheads und Lookbehinds:

(?<=\|)(2|3)(?=\|)

Die haben außerdem den Vorteil, dass das | nicht mit-gematcht wird.

Woher ich das weiß:Hobby – Programmieren ist mein Hobby & Beruf
TechPech1984  13.06.2022, 23:51

immer darauf achten , nicht jede regex bibliothek beherscht alles :)

0
MrAmazing2  13.06.2022, 23:54
@TechPech1984

Ja, leider. Die in Go kann zum Beispiel keine Lookaheads/Lookbehinds, größter Witz sowas.

0

nur genau die 2, aber weder 12, 20, 26 noch 28?

'|2|'

skyynet 
Fragesteller
 13.06.2022, 22:31

Wenn ich auf 2 prüfen will, dann quasi auf |2|. Wenn ich auf 20 prüfen will, auf |20|. Durch die senkrechten Striche vorher und nachher ist auch eindeutig eingrenzbar, was der geamte zu prüfende Teilstring ist.

Konkret habe ich in einer Tabellenzelle zu stehen, welche LTE oder 5G Kanäle ein Smartphone unterstützt und möchte gezielt eine Tabelle nach Geräten durchsuchen, die z.B. Kanal 2 unterstützen.

0
Bushmills145  13.06.2022, 22:33
@skyynet

Jo, das scheint mir ein brauchbarer Weg, um die Aufgabenstellung enorm zu vereinfachen. Seperatoren dürfen ja durchaus miteinbezogen werden - allerdings willst du sicherstellen, dass sowohl am Anfang als auch am Ende diese Seperatoren stehen.

0
skyynet 
Fragesteller
 13.06.2022, 22:42
@Bushmills145

Nur so kann ich ja sicherstellen, dass gegen die ganze Zahl geprüft wird. Würde ich z.B. den Strich vor der 1 am Anfang weglassen, könnte ich ja gar nicht gegen 11 testen. Jetzt fehlt mir nur noch der passende RegEx ;-)

0
MrAmazing2  13.06.2022, 22:46

Du musst die Striche escapen sonst werden sie als ODER gewertet.

0
skyynet 
Fragesteller
 13.06.2022, 23:57
@MrAmazing2

Danke. Ich nutze jetzt "/" als Separatoren in der Datenbank. Da ich ja mit der RegEx \b1\b prüfe, ist offensichtlich der Separator in der db egal. In der Query sollte ich auch mit \b(1|2|3)\b mehrere Werte checken können.

0

Um nur die 2 zu matchen:

\b2\b

\b ist eine "word boundary".

Um eine beliebige Zahl zu matchen:

\b(\d+)\b
Woher ich das weiß:Studium / Ausbildung – Informatikstudium
skyynet 
Fragesteller
 13.06.2022, 22:58

Danke! Du bist mein Held!

0
skyynet 
Fragesteller
 13.06.2022, 23:54

Ich habe das jetzt in meine MySQL Query eingebaut und leider bekomme ich keinen positiven Match. Meine Query lautet

SELECT * FROM database WHERE 5g REGEXP '\b1\b'

Wo ist mein Denkfehler?

Im Endeffekt würde ich nicht nur einen Vergleich machen, sondern mehrere, also

SELECT * FROM database WHERE 5g REGEXP '\b(1|5|78)\b'

Sicherlich ein ganz blöder Syntaxfehler.

0
VeryBestAnswers  14.06.2022, 00:13
@skyynet

Das Problem ist wahrscheinlich, dass du die Backslashes in MySQL Strings escapen musst:

SELECT * FROM database WHERE 5g REGEXP '\\b(1|5|78)\\b'
0