Skip to content

Instantly share code, notes, and snippets.

@patarapolw
Last active November 13, 2018 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patarapolw/f8072720d0685498621d96ddd03d0d01 to your computer and use it in GitHub Desktop.
Save patarapolw/f8072720d0685498621d96ddd03d0d01 to your computer and use it in GitHub Desktop.
Converting searchbox query string into computer-understandable list
import shlex
import json
import re
ADDITIONAL_CHAR = ''.join(re.findall(r'\w', re.escape(''.join(chr(u) for u in range(0x10FFFF)))))
def parse_query(q: str, operators=(':', '=', '>', '<')):
"""
:param str q:
:param list operators:
:return list|None:
>>> parse_query('')
>>> parse_query('a')
[['a']]
>>> parse_query('a:b')
[['a', ':', 'b']]
>>> parse_query('a:b c:d')
[['a', ':', 'b'], ['c', ':', 'd']]
>>> parse_query('a:b:c')
>>> parse_query("a:'b c'")
[['a', ':', 'b c']]
>>> parse_query("a:'b c")
>>> parse_query("'a b':c")
[['a b', ':', 'c']]
>>> parse_query("'a:b':c")
[['a:b', ':', 'c']]
>>> parse_query('tag:微信')
[['tag', ':', '微信']]
"""
if q:
try:
queue = []
sub_queue = []
shl = shlex.shlex(q)
shl.wordchars += ADDITIONAL_CHAR
for token in list(shl) + ['a']:
if token in operators:
if len(sub_queue) == 1:
sub_queue.append(token)
else:
return
else:
if token[0] == '"':
token = json.loads(token)
elif token[0] == "'":
token = json.loads(token
.replace("'", '\0')
.replace('"', "'")
.replace('\0', '"'))
if len(sub_queue) == 0:
sub_queue.append(token)
elif len(sub_queue) == 1:
queue.append(sub_queue)
sub_queue = [token]
elif len(sub_queue) == 2:
sub_queue.append(token)
elif len(sub_queue) == 3:
queue.append(sub_queue)
sub_queue = [token]
else:
return
except ValueError:
return
return queue
return
if __name__ == '__main__':
import doctest
doctest.testmod(verbose=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment