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?
SQLite3 supporte l'opérateur REGEXP:
WHERE x REGEXP <regex>
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.
Un moyen simple de le résoudre sans regex est where ',' || x || ',' like '%,3,%'
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.
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.
UPDATE TableName
SET YourField = ''
WHERE YourField REGEXP 'YOUR REGEX'
Et :
SELECT * from TableName
WHERE YourField REGEXP 'YOUR REGEX'
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
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.
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'
.
Pensez à utiliser ceci
WHERE x REGEXP '(^|,)(3)(,|$)'
Cela correspond exactement à 3 quand x est dans:
Autres exemples:
WHERE x REGEXP '(^|,)(3|13)(,|$)'
Cela correspondra sur 3 ou 13
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.
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,%');
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 )
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