ukulele-7
Goto Top

MSSQL regular expressions

Nabend

Ich habe ein bischen gebastelt und bin auf etwas für mich merkwürdiges gestoßen. Wenn ich eine Werteliste mit LIKE suche, funktioniert das. Auch funktionieren Wertebereiche aber beides kombinieren ist irgendwie sonderbar, vor allem wenn ich versuche Leerzeichen zu berücksichtigen.

funktioniert:
@Data LIKE '[AA,BB,CC]%'
@Data LIKE '[A-C][A-C]%'
@Data LIKE '[AA,BB,CC][A-C]%'

funktioniert nicht:
@Data LIKE '[AA,BB,CC][ ][A-C]%'
@Data LIKE '[AA,BB,CC] [A-C]%'
@Data LIKE '[AA ,BB ,CC ]%'
@Data LIKE '[AA,BB,CC]' + CHAR(32) + '%'

hier kommen sogar false positives zustande:
@Data = 'AA1'
@Data LIKE '[AA,BB,CC][A-C]%'

Sonderzeichen wie Punkt, Komma, etc. funktionieren auch in Wertelisten ganz gut. Aber mir ist irgendwie überhaupt nicht klar wann was funktioniert. Auch _ für ein belibiges Zeichen funktioniert an der Stelle des Leerzeichens nicht.

Content-Key: 435059

Url: https://administrator.de/contentid/435059

Ausgedruckt am: 28.03.2024 um 16:03 Uhr

Mitglied: GrueneSosseMitSpeck
GrueneSosseMitSpeck 01.04.2019 aktualisiert um 09:16:15 Uhr
Goto Top
Gibt eine Million Treffer mit "masking regular expressoins in sql". Blank ist übrigens \s

und hier steht der Rest:

Stackoverflow - Erklärung für Regex in Where klauseln
Mitglied: ukulele-7
ukulele-7 01.04.2019 aktualisiert um 10:40:33 Uhr
Goto Top
Zunächst mal Danke für den Versuch aber Google habe ich natürlich auch bemüht. Dein Treffer und \s etc. sind für MySQL, ich habe MSSQL 2014.
https://docs.microsoft.com/de-de/sql/t-sql/language-elements/like-transa ...

Meine Probleme haben eine andere Ursache. Scheinbar unterstützt LIKE die Angabe einer Werteliste mit , getrennt in eckigen Klammern nicht. Das scheint nur mit patindex() zu gehen.

PS: Okay unter gewissen umständen läuft es mit der Werteliste scheinbar, alles sehr seltsam.
Mitglied: 139374
139374 01.04.2019 aktualisiert um 19:09:04 Uhr
Goto Top
Baut man sich halt eine Regex Custom User Skalar Function für MSSQL face-smile
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlBoolean CheckRegex(string strPattern, string strValue) {
        Regex r = new Regex(strPattern);
        return r.IsMatch(strValue);
    }
}
Mitglied: MadMax
Lösung MadMax 03.04.2019 um 20:32:33 Uhr
Goto Top
Hallo ukulele,

das funktioniert schon alles richtig, auch Dein "false positive".

Was in eckige Klammern eingeschlossen ist, ist der mögliche Wertebereich für genau ein Zeichen. Da darfst Du auch Listen und Bereiche kombinieren. Steht übrigens sehr schön in der Hilfe zu dem Befehl like face-wink

Wenn Du ein bestimmtes Zeichen an einer Stelle suchst, dann brauchst Du auch keine eckigen Klammer, es sei denn, es ist ein Joker wie z.B. % oder _.

Dein Beispiel für das falsche Ergebnis erklärt sich also so:
@Data = 'AA1'
@Data LIKE '[AA,BB,CC][A-C]%'
Erstes Zeichen muß bei den Zeichen in der ersten eckigen Klammer sein, also A, B, C oder das Komma. Daß die Zeichen doppelt aufgeführt sind, stört offensichtlich nicht. Das erste Zeichen erfüllt jedenfalls die Bedingung, A ist in der Auflistung enthalten.
Das zweite Zeichen muß im Bereich A-C sein. das ist auch erfüllt.
Der Rest ist dann beliebig. Bedingung ist also erfüllt.

Wenn Du also am Anfang AA oder BB oder CC erwartest, dann müßtest Du das anders machen, nämlich:
@Data like 'AA%' or @Data like 'BB%' or @Data like 'CC%'
oder
left (@Data, 2) in ('AA', 'BB', 'CC')

Gruß, Mad Max
Mitglied: ukulele-7
ukulele-7 03.04.2019 um 21:43:04 Uhr
Goto Top
Ja danke nochmal für die Klarstellung. Nachdem ich nochmal alles nach "Wertelisten" mit mehr als einem Buchstaben abgesucht habe musste ich das auch so schlussfolgern. Offensichtlich habe ich hier früher theoretisch Fehler gemacht die aber nicht relevant waren, eben weil das , auch ein Wert war der gesucht wurde.

Auch wichtig zu wissen das patindex() und LIKE die selbe Syntax akzeptieren.

Leider suche ich im Text stellen die mit 2, 3 oder 4 Buchstaben anfangen, dann wahlweise einen Leerschritt haben oder eben auch nicht und auf die dann eine Zahl mit bis zu 7 Stellen folgt. Da es keine Möglichkeit gibt zwischen z.B. Leerschritt oder kein Zeichen in LIKE zu unterscheiden nur immer ziwschen Leerschritt oder einem anderen Zeichen (über die Werteliste) sind die möglichen Kombinationen zahlreich.

Ich werde versuchen es mit SQL Mitteln zu lösen, vielleicht baue ich mir hier eine Funktion. left() ist schon ein sinniger Ansatz, vielleicht in Kombination mit replace() um das Leerzeichen, falls vorhanden zu killen.
Mitglied: MadMax
MadMax 04.04.2019 um 01:27:46 Uhr
Goto Top
Hallo ukulele,

für patindex hatte ich bis jetzt noch nicht wirklich Verwendung, aber ja, in der Hilfe steht, daß es wie like funktioniert.

Aber dann ist es doch relativ einfach, solche Texte aufzuteilen. Wenn es wirklich wie like funktioniert, findet man mit "select patinidex ('%[0-9]%', @Data)" die erste Ziffer. Ob davor ein Leerzeichen oder zwei bis vier Buchstaben stehen, kann man dann ja einfach ermitteln.

Gruß, Mad Max