我正在尝试使用转义的Unicode用户提供的搜索参数执行重新思考db匹配查询:
import re
from rethinkdb import RethinkDB
r = RethinkDB()
search_value = u"u05e5" # provided by user via flask
search_value_escaped = re.escape(search_value) # results in u'\u05e5' ->
# when encoded with "utf-8" gives "ץ" as expected.
conn = rethinkdb.connect(...)
results_cursor_a = r.db(...).table(...).order_by(index="id").filter(
lambda doc: doc.coerce_to("string").match(search_value)
).run(conn) # search_value works fine
results_cursor_b = r.db(...).table(...).order_by(index="id").filter(
lambda doc: doc.coerce_to("string").match(search_value_escaped)
).run(conn) # search_value_escaped spits an error
search_value_escaped的错误如下:
ReqlQueryLogicError: Error in regexp `ץ` (portion `ץ`): invalid escape sequence: ץ in:
r.db(...).table(...).order_by(index="id").filter(lambda var_1: var_1.coerce_to('string').match(u'\u05e5m'))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我尝试在 re.escape(( 之前/之后用"utf-8"进行编码,但相同的结果有不同的错误。我在搞砸什么?是我的代码中的某些内容还是某种错误?
编辑:.coerce_to('string'(将文档转换为"utf-8"编码的字符串。RethinkDB 还将查询转换为"utf-8",然后它匹配它们,因此即使它看起来像字符串中的 unicde 匹配,第一个查询也可以工作。
从外观上看,RethinkDB 拒绝转义的 unicode 字符,所以我编写了一个简单的解决方法,其中包含自定义转义,而无需实现我自己的替换字符逻辑(担心我必须错过一个并产生安全问题(。
import re
def no_unicode_escape(u):
escaped_list = []
for i in u:
if ord(i) < 128:
escaped_list.append(re.escape(i))
else:
escaped_list.append(i)
rv = "".join(escaped_list)
return rv
或单行:
import re
def no_unicode_escape(u):
return "".join(re.escape(i) if ord(i) < 128 else i for i in u)
这产生了转义"危险"字符所需的结果,并按照我的意愿与RethinkDB一起工作。