如何在SQLite查询中使用正则表达式?

时间:2011-02-21 21:43:16

标签: regex sqlite query-string

我想在sqlite中使用正则表达式,但我不知道如何。

我的表格中有一个字符串,如下所示:“3,12,13,14,19,28,32” 现在如果我输入“where x LIKE'3'”我也会得到包含13或32之类值的行, 但我想只获得该字符串中具有正好值3的行。

有谁知道如何解决这个问题?

17 个答案:

答案 0 :(得分:97)

正如其他人已经指出的那样,REGEXP调用用户定义的函数,该函数必须首先定义并加载到数据库中。也许一些sqlite发行版或GUI工具默认包含它,但我的Ubuntu安装没有。解决方案是

sudo apt-get install sqlite3-pcre

/usr/lib/sqlite3/pcre.so

中的可加载模块中实现Perl正则表达式

为了能够使用它,每次打开数据库时都必须加载它:

.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文件应该在某个地方可用。

答案 1 :(得分:66)

SQLite3支持REGEXP运算符:

WHERE x REGEXP <regex>

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

答案 2 :(得分:29)

没有正则表达式的解决方法是where ',' || x || ',' like '%,3,%'

答案 3 :(得分:19)

默认情况下,SQLite不包含正则表达式功能。

它定义了一个REGEXP运算符,但除非您或您的框架define a user function调用regexp(),否则会失败并显示错误消息。如何执行此操作取决于您的平台。

如果您定义了regexp()函数,则可以匹配逗号分隔列表中的任意整数,如下所示:

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

但实际上,如果你normalised your database structure将逗号分隔列表中的每个数字替换为groups within a single column一个单独的行,看起来你会发现事情变得容易多了。然后,您不仅可以使用=运算符而不是正则表达式,还可以使用更强大的关系工具,例如SQL为您提供的连接。

答案 4 :(得分:14)

PHP / PDO中的SQLite UDF,用于模仿MySQL中行为的REGEXP关键字:

$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中一样。

答案 5 :(得分:4)

我回答一年前发布的问题并不好。但我正在为那些认为Sqlite本身提供函数 REGEXP 的人写这篇文章。

在sqlite中调用函数REGEXP的一个基本要求是
“您应该在应用程序中创建自己的函数,然后提供sqlite驱动程序的回调链接”
为此你必须使用sqlite_create_function(C接口)。您可以在herehere

中找到详细信息

答案 6 :(得分:4)

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

并且:

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

答案 7 :(得分: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。

答案 8 :(得分:3)

使用python,假设setTimeInterval是与SQLite的连接,则可以通过编写以下内容来定义所需的UDF:

setTimeout

这是一个更完整的示例:

con

答案 9 :(得分:2)

考虑使用此

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

当x在:

时,这将完全匹配3
  • 3
  • 3,12,13
  • 12,13,3
  • 12,3,13

其他例子:

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

这将匹配3或13

答案 10 :(得分:2)

你可以使用REGEXP的正则表达式,但这是一种完全匹配的愚蠢方法。

你应该说WHERE x = '3'

答案 11 :(得分:1)

详尽的or'ed where子句可以在没有字符串连接的情况下完成:

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

包括四种情况完全匹配,列表结尾,列表开头和中间列表。

这更详细,不需要正则表达式扩展。

答案 12 :(得分:0)

如果您使用的是php,可以使用:SQLite3::createFunction将任何函数添加到sql语句中。 在PDO中,您可以使用PDO::sqliteCreateFunction并在语句中实现preg_match函数:

了解Havalite(RegExp in SqLite using Php

的完成情况

答案 13 :(得分:0)

您也可以考虑

tblLocation

这将允许在任何位置的任何字符串中找到数字3

答案 14 :(得分:0)

如果有人寻找 Android Sqlite 的非正则表达式条件,例如字符串[1,2,3,4,5],请不要忘记添加括号( [] )与其他特殊字符(如@phyatt条件中的括号( {} ))相同

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

答案 15 :(得分:0)

在Julia中,可以遵循的模型如下所示:

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

答案 16 :(得分:0)

用于导轨

            db = ActiveRecord::Base.connection.raw_connection
            db.create_function('regexp', 2) do |func, pattern, expression|
              func.result = expression.to_s.match(Regexp.new(pattern.to_s, Regexp::IGNORECASE)) ? 1 : 0
            end