154 votes

Comment utiliser les regex dans une requête SQLite?

Je voudrais utiliser une expression régulière dans sqlite, mais je ne sais pas comment faire.

Ma table contient une colonne avec des chaînes de caractères comme ceci : "3,12,13,14,19,28,32" Maintenant, si je tape "where x LIKE '3'", je récupère également les lignes qui contiennent des valeurs comme 13 ou 32, mais je voudrais obtenir uniquement les lignes qui ont exactement la valeur 3 dans cette chaîne.

Est-ce que quelqu'un sait comment résoudre cela ?

3 votes

Cette réponse est la meilleure pour ajouter la fonction REGEXP à sqlite en c# stackoverflow.com/a/26155359/5734452

150voto

mivk Points 1352

Comme d'autres l'ont déjà mentionné, REGEXP appelle une fonction définie par l'utilisateur qui doit d'abord être définie et chargée dans la base de données. Peut-être que certaines distributions sqlite ou des outils GUI l'incluent par défaut, mais mon installation Ubuntu ne l'avait pas. La solution était

sudo apt-get install sqlite3-pcre

qui implémente des expressions régulières Perl dans un module chargeable dans /usr/lib/sqlite3/pcre.so

Pour pouvoir l'utiliser, vous devez le charger à chaque fois que vous ouvrez la base de données :

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

Ou vous pourriez mettre cette ligne dans votre ~/.sqliterc.

Maintenant vous pouvez faire une requête comme ceci:

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

Si vous souhaitez faire une requête directement à partir de la ligne de commande, vous pouvez utiliser l'option -cmd pour charger la bibliothèque avant votre requête SQL:

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

Si vous êtes sur Windows, je suppose qu'un fichier .dll similaire devrait être disponible quelque part.

20 votes

Une autre option de chargement : j'ai créé une vue avec ceci : SELECT load_extension('/usr/lib/sqlite3/pcre.so'); De cette façon, lorsque j'utilise un point d'entrée basé sur GUI vers la base de données (comme SQLite Manager dans Firefox), j'ai un moyen de charger la capacité REGEXP.

0 votes

Alors, qu'en est-il pour Windows?

8 votes

SQLite version 3.36.0 publiée le 18 juin 2021 a maintenant la commande REGEXP intégrée à l'interpréteur de commandes.

116voto

DanS Points 4992

SQLite3 prend en charge l'opérateur REGEXP :

WHERE x REGEXP 

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

4 votes

J'ai trouvé un moyen simple : c'est simplement \bx\b où x est la valeur à rechercher dans la chaîne :)

15 votes

@DanS: Comment ajoutez-vous une fonction regex() pour prendre en charge l'opérateur REGEXP? Par défaut, aucune fonction utilisateur n'a été ajoutée.

71 votes

Selon la documentation de Sqlite : L'opérateur REGEXP est une syntaxe spéciale pour la fonction utilisateur regexp(). Aucune fonction utilisateur regexp() n'est définie par défaut et donc l'utilisation de l'opérateur REGEXP entraînera généralement un message d'erreur. Si une fonction SQL définie par l'application nommée "regexp" est ajoutée à l'exécution, cette fonction sera appelée pour mettre en œuvre l'opérateur REGEXP. (sqlite.org/lang_expr.html#regexp)

38voto

Blorgbeard Points 38991

Une façon astucieuse de le résoudre sans regex est where ',' || x || ',' like '%,3,%'

1 votes

Oui, j'ai pensé à cette façon, mais il n'y a pas de virgule en tête ou en fin à chaque fois. Merci quand même :-)

0 votes

Je n'ai pas rencontré le problème ici - je me demande si cela fonctionne comme x est le nom de la colonne...

3 votes

Vous devriez utiliser ',' || x || ','

30voto

Ian Mackinnon Points 1993

SQLite ne contient pas de fonctionnalité d'expression régulière par défaut.

Il définit un opérateur REGEXP, mais cela échouera avec un message d'erreur à moins que vous ou votre framework ne définissiez une fonction utilisateur appelée regexp(). La manière de le faire dépendra de votre plateforme.

Si vous avez une fonction regexp() définie, vous pouvez faire correspondre un entier arbitraire à partir d'une liste séparée par des virgules comme ceci :

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

Mais en réalité, il semble que vous trouveriez les choses beaucoup plus faciles si vous normalisiez la structure de votre base de données en remplaçant ces groupes au sein d'une seule colonne par une ligne distincte pour chaque nombre dans la liste séparée par des virgules. Ensuite, vous pourriez non seulement utiliser l'opérateur = au lieu d'une expression régulière, mais également utiliser des outils relationnels plus puissants comme les jointures que SQL vous propose.

19voto

Alix Axel Points 63455

Un UDF SQLite en PHP/PDO pour le mot-clé REGEXP qui imite le comportement de MySQL:

$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;
    }
);

Le modificateur u n'est pas implémenté dans MySQL, mais je le trouve utile de l'avoir par défaut. Exemples:

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

Si $data ou $pattern est NULL, le résultat est NULL - tout comme dans MySQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X