我在尝试使用全局模式查询数据库时遇到了麻烦。
我认为也许可以将glob转换为regex,而且我知道我可以使用regex查询db。我本来打算进行翻译,但是我发现python具有fnmatch来做到这一点,显式地实现了该功能translate
fnmatch.translate(pattern)
返回转换为正则表达式的shell样式模式,以与re.match()一起使用。
所以我试图将两者结合起来,但是...
>>> from vte.models import VTE
>>> import fnmatch
>>> regex = fnmatch.translate('19*')
>>> regex
'19.*\\Z(?ms)'
>>> VTE.objects.filter(ipaddr__regex=regex)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 234, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 258, in __iter__
self._fetch_all()
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 1074, in _fetch_all
self._result_cache = list(self.iterator())
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 52, in __iter__
results = compiler.execute_sql()
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 848, in execute_sql
cursor.execute(sql, params)
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/var/www/vtfx/env/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
DataError: invalid regular expression: quantifier operand invalid
我不明白该错误信息。
根据django的文档,应该在postgresql(顺便说一句,我正在使用的数据库)中将其翻译成这样的东西
SELECT ... WHERE ipaddr ~ '19.*\\Z(?ms)';
因此,我尝试更改了由所返回的regexp translate()
,并且在删除?
char时不会引发错误。
然后我想,也许glob-> regex翻译在没有最后一部分的情况下可以正常工作,\\Z(?ms)
但是我不确定,我可能会遗漏一些东西。
回顾:
19.*\\Z(?ms)
19.*\\Z(ms)
19.*
所以新的代码将像这样
>>> VTE.objects.filter(ipaddr__regex=regex.replace('\\Z(?ms)', ''))
[<VTE: 192.168.56.100>]
我在做什么时会想念什么.replace('\\Z(?ms)', '')
?为什么那是必要的?这是一个好的解决方案吗?
根据对我的问题的评论,我最终做了以下工作
import fnmatch
globex = ......
regex = '^{}'.format(fnmatch.translate(globex).replace('\\Z(?ms)', '$'))
VTE.objects.filter(ipaddr__regex=regex)
这似乎与postgresql和javascript regex实现兼容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句