Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
100 lines (76 sloc) 3.11 KB
#-*- coding: iso-8859-1 -*
##
## Split search string - Useful when building advanced search application
## By: Peter Bengtsson, mail@peterbe.com
## May 2008
## ZPL
##
__version__='1.0'
"""
split_search(searchstring [str or unicode],
keywords [list or tuple])
Splits the search string into a free text part and a dictionary of keyword
pairs. For example, if you search for 'Something from: Peter to: Lukasz'
this function will return
'Something', {'from':'Peter', 'to':'Lukasz'}
It works equally well with unicode strings.
Any keywords in the search string that isn't recognized is considered text.
"""
import re
def split_search(q, keywords):
params = {}
s = []
regex = re.compile(r'\b(%s):' % '|'.join(keywords), re.I)
bits = regex.split(q)
skip_next = False
for i, bit in enumerate(bits):
if skip_next:
skip_next = False
else:
if bit in keywords:
params[bit.lower()] = bits[i+1].strip()
skip_next = True
elif bit.strip():
s.append(bit.strip())
return ' '.join(s), params
if __name__=='__main__':
import unittest
class Test(unittest.TestCase):
def test_basic(self):
""" one free text part, two keywords """
keywords = ('to','from')
q = "Peter something to:AAa aa from:Foo bar"
s, params = split_search(q, keywords)
self.assertEqual(s, 'Peter something')
self.assertEqual(params, {'to': 'AAa aa', 'from': 'Foo bar'})
def test_unrecognized_keywords(self):
""" free text and keywords we don't support """
keywords = ('something','else')
q = "Free text junk: Aaa aaa foo:bar"
s, params = split_search(q, keywords)
self.assertEqual(s, q)
self.assertEqual(params, {})
def test_unrecognized_and_recognized_keywords(self):
""" free text and keywords we don't support """
keywords = ('something','else','name')
q = "Free text junk: something else name: peter"
s, params = split_search(q, keywords)
self.assertEqual(s, 'Free text junk: something else')
self.assertEqual(params, {'name': 'peter'})
def test_empty_keyword_value(self):
""" free text and an empty keyword """
keywords = ('to',)
q = "Naughty parameter to:"
s, params = split_search(q, keywords)
self.assertEqual(s, "Naughty parameter")
self.assertEqual(params, {'to':''})
def test_unicode_string(self):
""" test with unicode string input """
keywords = ('from','to')
q = u"\xa1 to:\xa2 from:\xa3"
s, params = split_search(q, keywords)
self.assertEqual(s, u'\xa1')
self.assertEqual(params, {u'to': u'\xa2', u'from': u'\xa3'})
def suite():
return unittest.makeSuite(Test)
unittest.main()