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


102

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

我的表中有一列包含这样的字符串:“ 3,12,13,14,19,28,32”现在,如果我键入“ where x LIKE'3'”,我还将得到包含诸如13或32这样的值的行,但我只想获取该字符串中具有确切值为3的行。

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


这个答案是将REGEXP函数添加到c#中的sqlite的最佳方法stackoverflow.com/a/26155359/5734452
hubaishan

Answers:


74

SQLite3支持REGEXP运算符:

WHERE x REGEXP <regex>

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


3
我找到了一种简单的方法:它只是\ bx \ b,其中x是要在字符串中查找的值:)
cody

12
@DanS:您如何添加regex()功能以支持REGEXP操作员?默认情况下,未添加用户功能。
SK9

47
根据Sqlite文档:REGEXP运算符是regexp()用户函数的一种特殊语法。默认情况下,没有定义regexp()用户函数,因此使用REGEXP运算符通常会导致错误消息。如果在运行时添加了名为“ regexp”的应用程序定义的SQL函数,则将调用该函数以实现REGEXP运算符。(sqlite.org/lang_expr.html#regexp
开方

对于我们这些在尝试此操作时出错的人,请查看stackoverflow.com/a/18484596/1585572下面的响应,我将代码放入文件中,并将其导入到Firefox sqlite管理器中的用户定义函数中。但是,您需要以稍微不同的方式调用它,例如:SELECT * FROM table WHERE column regexp(“ myregexp”)
Tristan

112

正如其他人已经指出的那样,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的DB入口点(如Firefox中的SQLite Manager)时,就有一种加载REGEXP功能的方法。
Paulb 2012年

30

一种无需正则表达式的解决方法是 where ',' || x || ',' like '%,3,%'


1
是的,我是这样想的,但是并不是每次都在“,”之前或之后。无论如何,谢谢:-)
Cody

我没有在这里碰到问题-我想知道这是否适用,因为x是列名...
cody

3
您应该使用',' || x || ','
Baruch

21

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

它定义了一个REGEXP运算符,但是除非您或您的框架定义一个名为的用户函数,否则它将失败并显示一条错误消息regexp()。您如何执行此操作将取决于您的平台。

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

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

但是,实际上,如果通过用逗号分隔列表中的每个数字的单独行替换单个列中的那些组来规范化数据库结构,您会发现事情容易得多。然后,您不仅可以使用运算符代替正则表达式,而且可以使用SQL提供给您的更强大的关系工具,例如联接。=


14

PHP / PDO中的SQLite UDF,用于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中一样。


8

我与sqlite3在python中的解决方案:

   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。


5

我不愿意回答将近一年前发布的问题。但是我是为那些认为Sqlite本身提供功能REGEXP的人写的

在sqlite中调用功能REGEXP的一项基本要求是
“您应该在应用程序中创建自己的函数,然后提供指向sqlite驱动程序的回调链接”
为此,您必须使用sqlite_create_function(C接口)。您可以在这里这里找到详细信息


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

和:

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

4

详尽的or'ed where子句无需字符串连接即可完成此操作:

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

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

这比较冗长,不需要regex扩展名。


4

使用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' ")


恕我直言检查应该if x not Null and y not Null and re.search(x,y)否则将抛出。
pholat,

2

您可以将正则表达式与REGEXP一起使用,但这是进行精确匹配的一种愚蠢的方法。

你应该说WHERE x = '3'


我应该更好地解释它(对不起我的英语不好),我的意思是只给出一个确切的值,而不是确切的字符串。不管怎么说,还是要谢谢你!
科迪

2

考虑使用此

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

当x位于时,它将恰好匹配3:

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

其他例子:

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

这将匹配3或13


1

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

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


0

您也可以考虑

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

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


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

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.