Python中的"ValueError:不支持的格式字符'"(0x22)at ..."

jde*_*ero 1 python regex string list

我见过几个类似的线程,但试图逃避字符并不适合我.

简而言之,我有一个字符串列表,我正在迭代,这样我的目标是构建一个查询,将列表中的许多字符串合并到一个'Select,Like'查询中.

这是我的代码(Python)

def myfunc(self, cursor, var_list):
   query = "Select var FROM tble_tble WHERE"
   substring = []
   length = len(var_list)
   iter = length

   for var in var_list:
      if (iter != length):
         substring.append(" OR tble_tble.var LIKE %'%s'%" % var)
      else:
         substring.append(" tble_tble.var LIKE %'%s'%" % var)
      iter = iter - 1

   for str in substring:
      query = query + str
...
Run Code Online (Sandbox Code Playgroud)

那应该够了.如果从我之前声明的声明中不明显,我正在尝试构建一个查询,该查询在相关字符串列表运行SQL"LIKE"比较.

感谢您的时间,并随时提出任何问题以澄清.

aba*_*ert 7

首先,您的问题与SQL无关.扔掉所有与SQL相关的代码并执行以下操作:

var = 'foo'
" OR tble_tble.var LIKE %'%s'%" % var
Run Code Online (Sandbox Code Playgroud)

你会得到同样的错误.这是因为你正在尝试%使用带有迷路%符号的字符串进行格式化.因此,它试图弄清楚该怎么做%',然后失败.


你可以逃避这样的迷路%迹象:

" OR tble_tble.var LIKE %%'%s'%%" % var
Run Code Online (Sandbox Code Playgroud)

但是,这可能不是你想要做的.


首先,考虑使用{}-formatting而不是%-formatting,尤其是当您尝试构建带有%字符的格式化字符串时.它避免了逃避它们的需要.所以:

" OR tble_tble.var LIKE %'{}'%".format(var)
Run Code Online (Sandbox Code Playgroud)

但是,更重要的是,你根本不应该做这种格式化.不要将值格式化为SQL字符串,只需将它们作为SQL参数传递.如果您使用的是sqlite3,请使用?参数标记; 为MySQL,%s; 对于不同的数据库,请阅读其文档.所以:

" OR tble_tble.var LIKE %'?'%"
Run Code Online (Sandbox Code Playgroud)

没有什么可以在这里出错,没有什么需要逃脱的.execute使用查询字符串调用时,[var]以args身份传递.

这样更简单,通常更快,并且巧妙地避免了处理边缘情况的大量愚蠢错误,最重要的是,它可以防止SQL注入攻击.

sqlite3的文档更详细地解释这一点:

通常,您的SQL操作需要使用Python变量中的值.您不应该使用Python的字符串操作来汇编查询...而是使用DB-API的参数替换.?在任何想要使用值的位置放置占位符,然后提供值元组作为游标execute()方法的第二个参数.(其他数据库模块可能使用不同的占位符,例如%s或:1.)...


最后,正如其他人在评论中指出的那样,在LIKE条件允许的情况下,你必须将百分号放在引号内,而不是在外面.所以,无论你采用哪种方式解决这个问题,你都会遇到另一个问题需要解决.但那个应该容易多了.(如果没有,你可以随时回来问另一个问题.)