如何在Tcl中使用sqlite3进行正则表达式匹配

4
我想在我的Tcl项目中包含正则表达式,但是当我运行代码时,出现了以下错误:

没有这个函数:REGEXP

我的代码如下:

return [brain eval "select * from bad WHERE input REGEXP '^(.){0}_'"]

我可以在数据库中测试这段准确的代码(我正在使用BD浏览器来浏览数据库),它能够正确运行:

select * from uniq WHERE input REGEXP '^(.){1}0'

从"select * from uniq WHERE input REGEXP '^(.){1}0'"返回20行(用时18ms)

因此,REGEXP将在浏览器中工作,但不会在我的Tcl脚本中工作。以下是我在这个问题上所发现的内容:

  1. 有人在ruby中遇到了同样的问题:如何在SQLite3和Rails 3.1中打开REGEXP?
  2. iOS中也有人遇到了同样的问题,不得不创建create_sqlite_function:iOS上的sqlite3中没有这样的函数:REGEXP
  3. 如何在SQLite中编写一个函数:https://www.sqlite.org/c3ref/create_function.html
  4. 如何为Tcl编写SQLite函数:https://www.sqlite.org/tclsqlite.html
  5. 我可能需要在ruby中编写的函数示例:https://github.com/sei-mi/sqlite3_ar_regexp/blob/master/lib/sqlite3_ar_regexp/extension.rb
  6. 默认情况下未定义REGEXP用户函数:http://www.sqlite.org/lang_expr.html#regexp
  7. REGEXP用户定义函数的PHP示例:如何在SQLite查询中使用正则表达式?

所以我得出结论,我必须自己编写某种函数才能使其正常工作,但我不知道这个函数应该是什么样子的。它只是将我制作的正则表达式传递给sqlite3吗?还是将正则表达式转换为其他内容然后再传递?

这个函数会像这样吗?

file mkdir db
sqlite3 db ./brain/brain.sqlite -create true

db eval { create_function('regexp', 2) do |func, pattern, expression|
            func.result = expression.to_s.match(
            Regexp.new(pattern.to_s, Regexp::IGNORECASE)) ? 1 : 0
         end
         }  

感谢您能够提供给我任何帮助或建议!

1个回答

6

启用正则表达式处理其实非常简单。只需要使用function方法(假设db是你的连接句柄)即可:

db function regexp -deterministic {regexp --}

这告诉SQLite创建函数,它是确定性的(因为正则表达式匹配肯定是确定性的),并且应该通过将参数传递给regexp --来工作(--可以防止以-开头的REs引起问题)。

从此会话日志中可以看到:

% package require sqlite3
3.8.10.2
% sqlite3 db :memory:
% db eval {select 1 where 'abc' regexp 'b'}
no such function: regexp
% db function regexp -deterministic {regexp --}
% db eval {select 1 where 'abc' regexp 'b'}
1

2
谢谢!看起来很简单,但我自己永远想不到这个!我还发现,使用“_”的LIKE操作符可以处理我使用正则表达式的大部分内容,因此这可能是其他遇到此问题的人的可行选择。 - MetaStack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接