如何在 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 查询中使用正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章