Last active
November 13, 2018 17:43
-
-
Save patarapolw/f8072720d0685498621d96ddd03d0d01 to your computer and use it in GitHub Desktop.
Converting searchbox query string into computer-understandable list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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