【问题标题】:Problem with regexp python and sqlite正则表达式 python 和 sqlite 的问题
【发布时间】:2023-03-29 15:02:02
【问题描述】:

我尝试在 sqlite 数据库上使用带有 python 的正则表达式检查带有模式的字符串。 当我尝试使用带有“的模式的搜索字符串”时遇到问题 例如:

cur.execute("insert into articles(id,subject) values (1,'aaa\"test\"')")
cur.execute("select id,subject from articles where id = 1")
print (cur.fetchall())

cur.execute("select subject from articles where  subject regexp '\"test\"' ")
print (cur.fetchall())

我应该在正则表达式之前 \" 其他方式编译器不喜欢...语法错误

[(1, 'aaa"test"')]
[] <????? should found 

有人知道怎么做吗?

我的正则表达式函数:con.create_function("regexp", 2, regexp)

【问题讨论】:

    标签: python regex sqlite


    【解决方案1】:

    另一个参数化查询示例...

    对于必须向数据库提供自己的 REGEX 函数的情况——我猜 Python sqlite3 并不总是默认设置它。

    在另一个示例中,自定义 REGEX 函数正在为每个匹配项编译相同的表达式。有办法解决这个问题。下面的示例在另一种定义 REGEX 操作的方式的底部也有注释。

    您可以通过为每个查询创建自定义函数并仅编译表达式一次,在每次使用表达式(针对每个匹配项)处理大量数据的查询时编译表达式. self._conn 下面是数据库连接,curs 是其中的一个游标。

        # Form an expression to match nicknames with the last 3 characters
        # varying.
        nick_expr = re.sub(r"[0-9_\-|]{0,3}$", r"[0-9_\-|]{0,3}$", nick)
        nick_expr = re.compile(nick_expr, re.I)
    
        # Create custom sqlite3 function using the compiled expression.
        self._conn.create_function("NICKEXPR",
                                   1,
                                   lambda nick: nick_expr.match(nick) != None)
    
        # Create temporary table from first pass query.
        curs.execute(
            """ CREATE TEMP TABLE temp_table1 AS
               SELECT  DISTINCT *
               FROM    users
               WHERE   NICKEXPR(nick)
                   OR  host LIKE ?
                   OR  (account<>'' AND account LIKE ?)
                   OR  (address<>'' AND address=?)
           """, (host, account, address))
    
        # Set up the REGEXP operator/function for the sqlite3 database.
        #self._conn.create_function(
        #                       'REGEXP', 2, 
        #                       lambda exp, item : re.find(exp, item) != None)
    

    【讨论】:

    • 警告 - 如果多个线程正在执行相同的查询,重新定义 NICKEXPR 可能会影响其他线程的查询。
    【解决方案2】:

    使用参数化的 sql。那么你就不需要自己转义引号了:

    import sqlite3
    import re
    
    def regexp(expr, item):
        reg = re.compile(expr)
        return reg.search(item) is not None
    
    conn = sqlite3.connect(':memory:')
    conn.create_function("REGEXP", 2, regexp)
    cursor = conn.cursor()
    cursor.execute('CREATE TABLE foo (bar TEXT)')
    cursor.executemany('INSERT INTO foo (bar) VALUES (?)',[('aaa"test"',),('blah',)])
    cursor.execute('SELECT bar FROM foo WHERE bar REGEXP ?',['"test"'])
    data=cursor.fetchall()
    print(data)
    

    产量

    [(u'aaa"test"',)]
    

    【讨论】:

    • 很好的答案!还需要防止 regexp() 中的 item 为 none,例如,第一行可以是“if item is None: return False”
    【解决方案3】:

    您可以使用三次转义或原始字符串。

    你的做法:

    >>> print("从主题正则表达式'\"test\"'"的文章中选择主题 从主题 regexp '"test"' 的文章中选择主题

    使用原始字符串,即r'string with a r in front'

    >>> print(r"从主题正则表达式'\"test\"'"的文章中选择主题 从主题 regexp '\"test\"' 的文章中选择主题

    或三次转义 (\\\):

    >>> print("从主题正则表达式'\\\"test\\\"'"的文章中选择主题 从主题 regexp '\"test\"' 的文章中选择主题

    【讨论】:

      猜你喜欢
      • 2010-11-22
      • 2010-10-20
      • 2014-11-29
      • 1970-01-01
      相关资源
      最近更新 更多