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

Posted

技术标签:

【中文标题】如何在 SQLite 查询中使用正则表达式?【英文标题】:How do I use regex in a SQLite query? 【发布时间】:2011-07-01 14:12:53 【问题描述】:

我想在sqlite中使用正则表达式,但我不知道怎么做。

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

有人知道怎么解决吗?

【问题讨论】:

这个答案是在c#***.com/a/26155359/5734452sqlite中添加REGEXP函数的最佳答案 【参考方案1】:

正如其他人已经指出的那样,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 文件可用。

【讨论】:

另一个加载选项:我用这个创建了一个视图: SELECT load_extension('/usr/lib/sqlite3/pcre.so');这样,当我使用基于 GUI 的数据库入口点(如 Firefox 中的 SQLite 管理器)时,我就有办法加载 REGEXP 功能。 那么,Windows 是什么? SQLite 版本 3.36.0 于 2021 年 6 月 18 日发布,现在在 shell 中内置了 REGEXP 命令。【参考方案2】:

SQLite3 支持 REGEXP 运算符:

WHERE x REGEXP <regex>

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

【讨论】:

我找到了一个简单的方法:它只是 \bx\b 其中 x 是要在字符串中查找的值 :) @DanS:如何添加regex() 函数来支持REGEXP 运算符?默认情况下未添加用户功能。 根据 Sqlite 文档: REGEXP 运算符是 regexp() 用户函数的特殊语法。默认情况下没有定义 regexp() 用户函数,因此使用 REGEXP 运算符通常会导致错误消息。如果在运行时添加了名为“regexp”的应用程序定义的 SQL 函数,则将调用该函数以实现 REGEXP 运算符。 (sqlite.org/lang_expr.html#regexp) 对于我们这些在尝试此操作时遇到错误的人,请查看***.com/a/18484596/1585572 下面的响应我将代码放在一个文件中,并将其导入到我的 Firefox sqlite 管理器中的用户定义函数中。您需要稍微不同地调用它,例如:SELECT * FROM table WHERE column regexp("myregexp") 这是一个公认的答案吗?请在***.com/a/8338515/828885 下方查看 mivk 评分较高的答案。【参考方案3】:

不使用正则表达式的解决方法是where ',' || x || ',' like '%,3,%'

【讨论】:

是的,我是这么想的,但是每次都没有引导或跟随“,”。无论如何谢谢:-) 我没有偶然发现这里的问题 - 我想知道这是否有效,因为 x 是列名...... 你应该使用',' || x || ','【参考方案4】:

SQLite 默认不包含正则表达式功能。

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

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

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

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

【讨论】:

【参考方案5】:

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

【讨论】:

我不知道这是可能的。太棒了!【参考方案6】:

我在 Python 中的解决方案with 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。

【讨论】:

【参考方案7】:

用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),否则会抛出。【参考方案8】:

我不适合回答差不多一年前发布的问题。但我是为那些认为 Sqlite 本身提供函数 REGEXP 的人写的。

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

【讨论】:

【参考方案9】:

一个详尽的 or'ed where 子句可以在没有字符串连接的情况下做到这一点:

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

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

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

【讨论】:

【参考方案10】:
UPDATE TableName
 SET YourField = ''
WHERE YourField REGEXP 'YOUR REGEX'

还有:

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

【讨论】:

【参考方案11】:

考虑使用这个

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

当 x 在时,这将精确匹配 3:

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

其他例子:

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

这将在 3 或 13 匹配

【讨论】:

【参考方案12】:

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

你应该说WHERE x = '3'

【讨论】:

我应该更好地解释它(对不起我的英语不好),我的意思只是一个确切的值,而不是确切的字符串。还是谢谢!【参考方案13】:

你也可以考虑

WHERE x REGEXP '(^|\D1)3(\D1|$)'

这将允许在任何位置的任何字符串中找到数字 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】:

2021-06-18 发布的 SQLite 版本 3.36.0 现在内置了 REGEXP 命令。

【讨论】:

参考:sqlite.org/releaselog/3_36_0.html【参考方案16】:

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

看看 Havalite (RegExp in SqLite using Php) 是如何做到的

【讨论】:

在 MySQL REGEXP 函数中,您不需要在模式中指定分隔符或修饰符。【参考方案17】:

在 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

【讨论】:

【参考方案18】:

用于导轨

            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

【讨论】:

以上是关于如何在 SQLite 查询中使用正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

使用正则表达式的 SQLite 查询

Python SQLite 正则表达式 ExecuteMany

mysql如何正则匹配查询

如何对子查询的结果使用正则表达式?

如何在配置单元中使用正则表达式排除字符串中的特殊字符

如何在 php 中使用正则表达式中断查询