Как использовать регулярные выражения в запросе SQLite?

83

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

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

Кто-нибудь знает, как это решить?

  • 0
    Этот ответ лучше всего подходит для добавления функции REGEXP в sqlite в c # stackoverflow.com/a/26155359/5734452
Теги:
query-string

12 ответов

61
Лучший ответ

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

WHERE x REGEXP <regex>

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

  • 2
    Я нашел простой способ: это просто \ bx \ b, где x - это значение, которое нужно искать в строке :)
  • 11
    @DanS: Как добавить функцию regex() для поддержки оператора REGEXP ? По умолчанию пользовательская функция не была добавлена.
Показать ещё 2 комментария
95

Как уже указывали другие, 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';

Если вы хотите сделать запрос непосредственно из командной строки, вы можете использовать переключатель -cmd для загрузки библиотеки перед вашим SQL:

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

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

  • 15
    Другой вариант загрузки: я создал представление с помощью этого: SELECT load_extension ('/ usr / lib / sqlite3 / pcre.so'); Таким образом, когда я использую основанную на GUI точку входа в БД (например, SQLite Manager в Firefox), у меня есть способ загрузить возможность REGEXP.
28

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

  • 1
    Да, я думал об этом, но не всегда веду или следую ",". Спасибо, в любом случае :-)
  • 1
    @ cody, поэтому я добавляю запятые к x перед тестированием - это должно работать ..
Показать ещё 3 комментария
19

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

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

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

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

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

13

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.

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

И:

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

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

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

3

мое решение в 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.

2

Подумайте об использовании этого

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

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

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

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

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

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

2

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

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

  • 0
    Я должен был объяснить это лучше (извините за мой плохой английский), я имел в виду только определенное точное значение, а не точную строку. Спасибо, в любом случае!
0

Исключительное предложение or'ed where, которое может сделать это без конкатенации строк:

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

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

Это более подробный, не требует расширения регулярного выражения.

0

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

Посмотрите, как это сделано Havalite (RegExp в SqLite с использованием Php)

  • 0
    В функции MySQL REGEXP вам не нужно указывать разделители или модификаторы в шаблоне.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню