it-swarm.com.de

Wie verwende ich Regex in einer SQLite-Abfrage?

Ich würde gerne einen regulären Ausdruck in sqlite verwenden, aber ich weiß nicht wie.

Meine Tabelle hat eine Spalte mit Zeichenfolgen wie "3,12,13,14,19,28,32" Wenn ich nun "wo x LIKE '3" eingebe, bekomme ich auch die Zeilen, die Werte enthalten 13 oder 32, Ich möchte jedoch nur die Zeilen erhalten, die genau den Wert 3 in dieser Zeichenfolge haben.

Weiß jemand, wie man das löst?

83
cody

SQLite3 unterstützt den REGEXP-Operator:

WHERE x REGEXP <regex>

http://www.sqlite.org/lang_expr.html#regexp

60
DanS

Wie bereits erwähnt, ruft REGEXP eine benutzerdefinierte Funktion auf, die zuerst definiert und in die Datenbank geladen werden muss. Möglicherweise enthalten einige sqlite-Distributionen oder GUI-Tools dies standardmäßig, meine Ubuntu-Installation jedoch nicht. Die Lösung war

Sudo apt-get install sqlite3-pcre

die reguläre Perl-Ausdrücke in einem ladbaren Modul in /usr/lib/sqlite3/pcre.so implementiert

Um es verwenden zu können, müssen Sie es jedes Mal laden, wenn Sie die Datenbank öffnen:

.load /usr/lib/sqlite3/pcre.so

Oder Sie könnten diese Zeile in Ihren ~/.sqliterc setzen.

Jetzt können Sie so abfragen:

SELECT fld FROM tbl WHERE fld REGEXP '\b3\b';

Wenn Sie direkt von der Befehlszeile aus abfragen möchten, können Sie die Bibliothek -cmd verwenden, um die Bibliothek vor Ihrer SQL zu laden:

sqlite3 "$filename" -cmd ".load /usr/lib/sqlite3/pcre.so" "SELECT fld FROM tbl WHERE fld REGEXP '\b3\b';"

Wenn Sie Windows verwenden, sollte eine ähnliche .dll-Datei irgendwo verfügbar sein.

95
mivk

Eine gehackte Methode, um es ohne Regex zu lösen, ist where ',' || x || ',' like '%,3,%'

29
Blorgbeard

SQLite enthält standardmäßig keine regulären Ausdrücke.

Es definiert einen REGEXP-Operator. Dies schlägt jedoch mit einer Fehlermeldung fehl, es sei denn, Sie oder Ihr Framework definieren Sie eine Benutzerfunktion heißt regexp(). Wie Sie dies tun, hängt von Ihrer Plattform ab.

Wenn Sie eine regexp()-Funktion definiert haben, können Sie eine beliebige ganze Zahl aus einer durch Kommas getrennten Liste wie folgt zuordnen:

... WHERE your_column REGEXP "\b" || your_integer || "\b";

Es sieht jedoch so aus, als würden Sie die Dinge viel einfacher finden, wenn Sie Ihre Datenbankstruktur normalisiert durch Ersetzen dieser Gruppen innerhalb einer einzelnen Spalte durch eine separate Zeile für jede Zahl im Komma ersetzen -separierte Liste. Dann können Sie nicht nur den =-Operator anstelle eines regulären Ausdrucks verwenden, sondern auch leistungsfähigere relationale Tools wie Joins, die SQL für Sie bereitstellt.

19
Ian Mackinnon

Eine SQLite-UDF in PHP/PDO für das Schlüsselwort REGEXP, das das Verhalten in MySQL nachahmt: 

$pdo->sqliteCreateFunction('regexp',
    function ($pattern, $data, $delimiter = '~', $modifiers = 'isuS')
    {
        if (isset($pattern, $data) === true)
        {
            return (preg_match(sprintf('%1$s%2$s%1$s%3$s', $delimiter, $pattern, $modifiers), $data) > 0);
        }

        return null;
    }
);

Der Modifikator u ist nicht in MySQL implementiert, aber ich finde es nützlich, ihn standardmäßig zu haben. Beispiele:

SELECT * FROM "table" WHERE "name" REGEXP 'sql(ite)*';
SELECT * FROM "table" WHERE regexp('sql(ite)*', "name", '#', 's');

Wenn entweder $data oder $pattern NULL ist, ist das Ergebnis NULL - genau wie in MySQL.

13
Alix Axel
UPDATE TableName
 SET YourField = ''
WHERE YourField REGEXP 'YOUR REGEX'

Und :

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'
4
user4813855

Ich kann nicht auf eine Frage antworten, die vor fast einem Jahr gepostet wurde. Aber ich schreibe dies für diejenigen, die glauben, dass Sqlite selbst die Funktion REGEXP bereitstellt. 

Eine Grundvoraussetzung zum Aufrufen der Funktion REGEXP in sqlite ist
"Sie sollten Ihre eigene Funktion in der Anwendung erstellen und dann den Callback-Link zum sqlite-Treiber bereitstellen".
Dazu müssen Sie sqlite_create_function (C-Schnittstelle) verwenden. Das Detail finden Sie von hier und hier

4
Naved

meine Lösung in Python mit sqlite3:

   import sqlite3
   import re

   def match(expr, item):
        return re.match(expr, item) is not None

   conn = sqlite3.connect(':memory:')
   conn.create_function("MATCHES", 2, match)
   cursor = conn.cursor()
   cursor.execute("SELECT MATCHES('^b', 'busy');")
   print cursor.fetchone()[0]

   cursor.close()
   conn.close()

wenn der reguläre Ausdruck übereinstimmt, wäre die Ausgabe 1, andernfalls 0.

3
aGuegu

Sie könnten einen regulären Ausdruck mit REGEXP verwenden, aber das ist eine dumme Methode, um eine exakte Übereinstimmung herzustellen.

Sie sollten einfach WHERE x = '3' sagen.

2
Quentin

Erwägen Sie, dies zu verwenden

WHERE x REGEXP '(^|,)(3)(,|$)'

Dies wird genau 3 sein, wenn x in:

  • 3
  • 3,12,13
  • 12,13,3
  • 12,3,13

Andere Beispiele:

WHERE x REGEXP '(^|,)(3|13)(,|$)'

Dies wird auf 3 oder 13 passen

2
itsjavi

Eine erschöpfende or'ed where-Klausel kann dies ohne String-Verkettung tun:

WHERE ( x == '3' OR
        x LIKE '%,3' OR
        x LIKE '3,%' OR
        x LIKE '%,3,%');

Enthält die vier genauen Fälle, das Ende der Liste, den Beginn der Liste und die mittlere Liste.

Dies ist ausführlicher und erfordert nicht die Regex-Erweiterung.

1
phyatt

Für den Fall, dass jemand, der nach Android Sqlite ohne reguläre Ausdrücke sucht, wie diese Zeichenfolge [1,2,3,4,5] aussieht, vergessen Sie nicht, die gleiche Klammer ([]) für andere hinzuzufügen Sonderzeichen wie Klammern ({}) in @phyatt-Bedingung

WHERE ( x == '[3]' OR
        x LIKE '%,3]' OR
        x LIKE '[3,%' OR
        x LIKE '%,3,%');
0
dastan

Wenn Sie PHP verwenden, können Sie Ihrer SQL-Anweisung jede Funktion hinzufügen, indem Sie Folgendes verwenden: SQLite3 :: createFunction . In PDO können Sie PDO :: sqliteCreateFunction verwenden und preg_match implementieren. Funktion innerhalb Ihrer Aussage:

Sehen Sie, wie es von Havalite gemacht wird ( RegExp in SqLite mit PHP )

0
code19

Sie können auch berücksichtigen

WHERE x REGEXP '(^|\D{1})3(\D{1}|$)'

Auf diese Weise können Sie die Nummer 3 in einer beliebigen Zeichenfolge an einer beliebigen Position finden

0
Avrob