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

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

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

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

Ответ 2

Как уже указывали другие, 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 должен быть где-то доступен.

Ответ 3

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

Ответ 4

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

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

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

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

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

Ответ 5

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.

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

И:

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

Ответ 9

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

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

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

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

Ответ 10

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

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

Ответ 11

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

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

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

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

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

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

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

Ответ 13

Вы можете рассмотреть также

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

Это позволит найти номер 3 в любой строке в любой позиции

Ответ 14

В случае, если кто-то ищет условие не-регулярного выражения для Android Sqlite, например, такую строку [1,2,3,4,5], не забудьте добавить скобку ([]) для других специальных символов, таких как скобки ({}) в состоянии @phyatt

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

Ответ 15

В python, предполагая, что con является соединением с SQLite, вы можете определить требуемый UDF, написав:

con.create_function('regexp', 2, lambda x, y: 1 if re.search(x,y) else 0)

Вот более полный пример:

import re
import sqlite3

with sqlite3.connect(":memory:") as con:
    con.create_function('regexp', 2, lambda x, y: 1 if re.search(x,y) else 0)
    cursor = con.cursor()
    # ...
    cursor.execute("SELECT * from person WHERE surname REGEXP '^A' ")


Ответ 16

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

using SQLite
using DataFrames

db = SQLite.DB("<name>.db")

register(db, SQLite.regexp, nargs=2, name="regexp")

SQLite.Query(db, "SELECT * FROM test WHERE name REGEXP '^h';") |> DataFrame