web-dev-qa-db-fra.com

Comment utiliser regex dans une requête SQLite?

J'aimerais utiliser une expression régulière dans sqlite, mais je ne sais pas comment.

Ma table a une colonne avec des chaînes comme celle-ci: "3,12,13,14,19,28,32" Maintenant, si je tape "où x LIKE '3'", j'obtiens également les lignes contenant des valeurs telles que 13 ou 32, Mais je voudrais obtenir uniquement les lignes qui ont exactement la valeur 3 dans cette chaîne.

Quelqu'un sait-il comment résoudre ceci?

83
cody

SQLite3 supporte l'opérateur REGEXP:

WHERE x REGEXP <regex>

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

60
DanS

Comme d'autres l'ont déjà souligné, 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 certains outils graphiques l’incluent par défaut, mais mon installation Ubuntu ne l’a pas fait. 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 pouvez mettre cette ligne dans votre ~/.sqliterc.

Maintenant, vous pouvez interroger comme ceci:

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

Si vous souhaitez interroger directement à partir de la ligne de commande, vous pouvez utiliser le commutateur -cmd pour charger la bibliothèque avant votre code SQL:

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

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

95
mivk

Un moyen simple de le résoudre sans regex est where ',' || x || ',' like '%,3,%'

29
Blorgbeard

SQLite ne contient pas la 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 structure définissiez une fonction utilisateur appelée regexp(). Cela dépend de votre plate-forme.

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

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

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

19
Ian Mackinnon

Une UDF SQLite dans PHP/PDO pour le mot clé REGEXP qui imite le comportement dans 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 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 - comme dans MySQL.

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

Et :

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

Je ne pense pas qu'il soit bon de répondre à une question qui a été postée il y a presque un an. Mais j'écris ceci pour ceux qui pensent que Sqlite fournit lui-même la fonction REGEXP

Une condition de base pour appeler la fonction REGEXP dans sqlite est
"Vous devez créer votre propre fonction dans l'application, puis fournir le lien de rappel au pilote sqlite".
Pour cela, vous devez utiliser sqlite_create_function (interface C). Vous pouvez trouver le détail de ici et ici

4
Naved

ma solution en python avec 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()

si regex correspond, la sortie serait 1, sinon 0.

3
aGuegu

Vous pouvez utiliser une expression régulière avec REGEXP , mais c’est une façon idiote de faire une correspondance exacte.

Vous devriez juste dire WHERE x = '3'.

2
Quentin

Pensez à utiliser ceci

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

Cela correspond exactement à 3 quand x est dans:

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

Autres exemples:

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

Cela correspondra sur 3 ou 13

2
itsjavi

Une clause exhaustive 'ou' où peut le faire sans concaténation de chaînes:

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

Inclut la correspondance exacte dans quatre cas, la fin de la liste, le début de la liste et la liste intermédiaire.

Ceci est plus détaillé, ne nécessite pas l'extension regex.

1
phyatt

Si quelqu'un recherche une condition autre que regex pour Android Sqlite, comme cette chaîne [1,2,3,4,5], n'oubliez pas d'ajouter un crochet ([]) de même pour les autres Caractères spéciaux tels que parenthèses ({}) dans l'état @phyatt

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

Si vous utilisez php, vous pouvez ajouter n’importe quelle fonction à votre instruction SQL en utilisant: SQLite3 :: createFunction . Dans PDO, vous pouvez utiliser PDO :: sqliteCreateFunction et implémenter le preg_match fonctionner dans votre déclaration:

Voyez comment cela se fait par Havalite ( RegExp dans SqLite en utilisant Php )

0
code19

Vous pouvez aussi considérer

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

Cela permettra de trouver le numéro 3 dans n'importe quelle chaîne à n'importe quelle position

0
Avrob