Как использовать regex в запросе SQLite?

Я хотел бы использовать регулярное выражение в SQLite, но я не знаю как.

в моей таблице есть столбец со строками вроде этого: "3,12,13,14,19,28,32" Теперь, если я наберу " где x, как "3"", я также получу строки, содержащие значения, такие как 13 или 32, но я хотел бы получить только строки, которые имеют точно значение 3 в этой строке.

кто-нибудь знает как решить эту проблему?

12 ответов


SQLite3 поддерживает оператор REGEXP:

WHERE x REGEXP <regex>

как уже указывали другие, REGEXP вызывает пользовательскую функцию, которая сначала должна быть определена и загружена в базу данных. Возможно, некоторые дистрибутивы sqlite или инструменты GUI включают его по умолчанию, но моя установка Ubuntu этого не сделала. Решение

sudo apt-get install sqlite3-pcre

который реализует регулярные выражения Perl в загружаемом модуле в /usr/lib/sqlite3/pcre.so

чтобы иметь возможность использовать его, вы должны загружать его каждый раз, когда вы открываете базу данных:

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

или вы могли бы поставить это линия в ваш ~/.sqliterc.

теперь вы можете запросить следующее:

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

если вы находитесь на Windows, я думаю, похожие .dll файл должен быть доступен где-то.


хакерский способ решить его без регулярного выражения -where ',' || x || ',' like '%,3,%'


SQLite по умолчанию не содержит функций регулярных выражений.

определяет REGEXP оператор, но это не удастся с сообщением об ошибке, если вы или ваш фреймворк определите пользовательскую функцию под названием regexp(). Как вы это сделаете будет зависеть от вашей платформы.

если у вас regexp() функция определена, можно сопоставить произвольное целое число из списка, разделенного запятыми, например:

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

но на самом деле, похоже, вы найдете все намного проще, если вы нормализованная структура базы данных заменив те группы в пределах одного столбца С отдельной строкой для каждого номера в списке через запятую. Тогда вы не могли бы использовать только = оператор вместо регулярного выражения, но также использовать более мощные реляционные инструменты, такие как соединения, которые SQL предоставляет для вас.


SQLite UDF в PHP / PDO для REGEXP ключевое слово, которое имитирует поведение в 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;
    }
);

на u модификатор не реализован в MySQL, но я считаю полезным иметь его по умолчанию. Примеры:

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

если $data или $pattern равно NULL, результат равен NULL-так же, как в MySQL.


Я не могу ответить на вопрос, который был опубликован почти год назад. Но я пишу это для тех, кто думает, что Sqlite сам предоставляет функцию и.

одним из основных требований для вызова функции REGEXP в sqlite является
"вы должны создать свою собственную функцию в приложении, а затем предоставить ссылку обратного вызова драйверу sqlite".
Для этого вы должны использовать sqlite_create_function (интерфейс c). Вы можете найти деталь от здесь и здесь


UPDATE TableName
 SET YourField = ''
WHERE YourField REGEXP 'YOUR REGEX'

и :

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

вы можете использовать регулярное выражение с и, но это глупый способ сделать точное совпадение.

вы должны просто сказать WHERE x = '3'.


используйте этот

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

это будет соответствовать точно 3, Когда x находится в:

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

другие примеры:

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

это будет соответствовать 3 или 13


мое решение на python с 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()

если регулярное выражение совпадает, выход будет 1, в противном случае 0.


Если вы используете php, вы можете добавить любую функцию в свой оператор sql, используя:SQLite3:: createFunction. В PDO вы можете использовать PDO:: sqliteCreateFunction и реализовать функции preg_match


исчерпывающее предложение or'Ed where может сделать это без конкатенации строк:

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

включает в себя четыре случая точное совпадение, конец списка, начало списка и средний список.

Это более подробно, не требует расширения regex.