mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Search query parser: Fix parsing of search terms that contain a word that starts with 'and' or 'or' and is not the first word
This commit is contained in:
parent
6fa16aa3fa
commit
aa8eab9d35
@ -18,10 +18,12 @@ If this module is run, it will perform a series of unit tests.
|
|||||||
|
|
||||||
import sys, string, operator
|
import sys, string, operator
|
||||||
|
|
||||||
from calibre.utils.pyparsing import Keyword, Group, Forward, CharsNotIn, Suppress, \
|
from calibre.utils.pyparsing import CaselessKeyword, Group, Forward, CharsNotIn, Suppress, \
|
||||||
OneOrMore, oneOf, CaselessLiteral, Optional, NoMatch, ParseException
|
OneOrMore, MatchFirst, CaselessLiteral, Optional, NoMatch, ParseException
|
||||||
from calibre.constants import preferred_encoding
|
from calibre.constants import preferred_encoding
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
This class manages access to the preference holding the saved search queries.
|
This class manages access to the preference holding the saved search queries.
|
||||||
It exists to ensure that unicode is used throughout, and also to permit
|
It exists to ensure that unicode is used throughout, and also to permit
|
||||||
@ -149,18 +151,19 @@ class SearchQueryParser(object):
|
|||||||
|
|
||||||
Not = Forward()
|
Not = Forward()
|
||||||
Not << (Group(
|
Not << (Group(
|
||||||
Suppress(Keyword("not", caseless=True)) + Not
|
Suppress(CaselessKeyword("not")) + Not
|
||||||
).setResultsName("not") | Parenthesis)
|
).setResultsName("not") | Parenthesis)
|
||||||
|
|
||||||
And = Forward()
|
And = Forward()
|
||||||
And << (Group(
|
And << (Group(
|
||||||
Not + Suppress(Keyword("and", caseless=True)) + And
|
Not + Suppress(CaselessKeyword("and")) + And
|
||||||
).setResultsName("and") | Group(
|
).setResultsName("and") | Group(
|
||||||
Not + OneOrMore(~oneOf("and or", caseless=True) + And)
|
Not + OneOrMore(~MatchFirst(list(map(CaselessKeyword,
|
||||||
|
('and', 'or')))) + And)
|
||||||
).setResultsName("and") | Not)
|
).setResultsName("and") | Not)
|
||||||
|
|
||||||
Or << (Group(
|
Or << (Group(
|
||||||
And + Suppress(Keyword("or", caseless=True)) + Or
|
And + Suppress(CaselessKeyword("or")) + Or
|
||||||
).setResultsName("or") | And)
|
).setResultsName("or") | And)
|
||||||
|
|
||||||
if test:
|
if test:
|
||||||
@ -291,7 +294,7 @@ class Tester(SearchQueryParser):
|
|||||||
28: [u"Kushiel's Scion", u'Jacqueline Carey', None, u'lrf,rar'],
|
28: [u"Kushiel's Scion", u'Jacqueline Carey', None, u'lrf,rar'],
|
||||||
29: [u'Underworld', u'Don DeLillo', None, u'lrf,rar'],
|
29: [u'Underworld', u'Don DeLillo', None, u'lrf,rar'],
|
||||||
30: [u'Genghis Khan and The Making of the Modern World',
|
30: [u'Genghis Khan and The Making of the Modern World',
|
||||||
u'Jack Weatherford',
|
u'Jack Weatherford Orc',
|
||||||
u'Three Rivers Press',
|
u'Three Rivers Press',
|
||||||
u'lrf,zip'],
|
u'lrf,zip'],
|
||||||
31: [u'The Best and the Brightest',
|
31: [u'The Best and the Brightest',
|
||||||
@ -543,6 +546,7 @@ class Tester(SearchQueryParser):
|
|||||||
'london:thames': set([13]),
|
'london:thames': set([13]),
|
||||||
'publisher:london:thames': set([13]),
|
'publisher:london:thames': set([13]),
|
||||||
'"(1977)"': set([13]),
|
'"(1977)"': set([13]),
|
||||||
|
'jack weatherford orc': set([30]),
|
||||||
}
|
}
|
||||||
fields = {'title':0, 'author':1, 'publisher':2, 'tag':3}
|
fields = {'title':0, 'author':1, 'publisher':2, 'tag':3}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user