首页 > 解决方案 > 在 SQLite SELECT 语句中使用 Python 正则表达式代码

问题描述

我正在尝试使用正则表达式从存储在表列中的文件名中提取子字符串。所以我使用了一个自定义的python函数:

In [1]: import sqlite3, re
In [2]: def search(expr, item):
   ...:     return re.search(expr, item).group()
   ...:
In [3]: conn = sqlite3.connect(':memory:')
In [4]: conn.create_function('SEARCH_REGEXP', 2, search)
In [5]: regexp = '[0-9]+\.[0-9]+\.(docx|pdf|rtf|doc)$'
In [6]: sql = "select SEARCH_REGEXP('%s', filename) from file_list;" % regexp
In [7]: cursor = conn.cursor()
In [8]: cursor.execute('CREATE TABLE "file_list" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, "filename" TE
   ...: XT);')
Out[8]: <sqlite3.Cursor at 0x1b7eafb7dc0>
In [9]: cursor.execute("INSERT INTO file_list(filename) VALUES ('filename.1.0.pdf'), ('filename.2.0.pdf');")
Out[9]: <sqlite3.Cursor at 0x1b7eafb7dc0>
In [10]: cursor.execute('select * from file_list;')
Out[10]: <sqlite3.Cursor at 0x1b7eafb7dc0>
In [11]: cursor.fetchall()
Out[11]: [(1, 'filename.1.0.pdf'), (2, 'filename.2.0.pdf')]
In [12]: cursor.execute(sql)
Out[12]: <sqlite3.Cursor at 0x1b7eafb7dc0>
In [13]: cursor.fetchall()
Out[13]: [('1.0.pdf',), ('2.0.pdf',)]

现在,我插入一个与 reg exp 不匹配的值:

In [14]: cursor.execute("INSERT INTO file_list(filename) VALUES ('filename.pdf');")
Out[14]: <sqlite3.Cursor at 0x1b7eafb7dc0>

但这现在会引发异常:

In [15]: cursor.execute(sql)
Out[15]: <sqlite3.Cursor at 0x1b7eafb7dc0>
In [16]: cursor.fetchall()
---------------------------------------------------------------------------
OperationalError                          Traceback (most recent call last)
<ipython-input-17-d35fc1caa8d6> in <module>
----> 1 cursor.fetchall()

OperationalError: user-defined function raised exception

我应该如何处理,例如用户定义的函数在不匹配的情况下返回一个空字符串?

谢谢!

R。

标签: pythonregexsqlite

解决方案


这是因为,在您的search函数中,当没有匹配项时re.search(expr, item)返回。None因为Noneis not a MatchObject,所以会引发异常。

group()只有在匹配时才能调用:

def search(expr, item):
   result =  re.search(expr, item)
   if result != None:
        return result.group()
   else:
        return tuple() #See note below

注意:您还需要考虑当没有匹配时应该做什么,以避免其他类似的问题。我在这里返回一个空元组,因为group()返回一个元组,但您可能想做其他事情。


推荐阅读