Использование кода регулярного выражения Python в выражении SQLite SELECT - PullRequest
2 голосов
/ 20 мая 2019

Я пытаюсь извлечь подстроки из имен файлов, хранящихся в столбце таблицы, используя регулярное выражение.Поэтому я использую пользовательскую функцию 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.

1 Ответ

2 голосов
/ 20 мая 2019

Это потому, что в вашей функции search, re.search(expr, item) возвращает None, когда нет совпадений. Поскольку None не является MatchObject, возникнет исключение.

Вы можете позвонить group() только в случае совпадения:

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

ПРИМЕЧАНИЕ. Вам также следует подумать о том, что следует делать, когда нет совпадения, чтобы избежать других подобных проблем. Я возвращаю пустой кортеж здесь, потому что group() возвращает кортеж, но вы можете захотеть сделать что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...