From 724cb02e3e7a98e58387e80c9360b420a09b3607 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Mon, 27 Oct 2014 18:26:53 +0100 Subject: new search query parser; support for NOT --- lib/search/queryparser.php | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 lib/search/queryparser.php (limited to 'lib/search/queryparser.php') diff --git a/lib/search/queryparser.php b/lib/search/queryparser.php new file mode 100644 index 0000000..7e96aaa --- /dev/null +++ b/lib/search/queryparser.php @@ -0,0 +1,98 @@ + + * @copyright 2014 Christian Weiske + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 + * @link http://cweiske.de/grauphel.htm + */ +namespace OCA\Grauphel\Search; + +/** + * User search query parser + * + * @category Tools + * @package Grauphel + * @author Christian Weiske + * @copyright 2014 Christian Weiske + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 + * @version Release: @package_version@ + * @link http://cweiske.de/grauphel.htm + */ +class QueryParser +{ + /** + * Splits the user's query string up into several keywords + * that all have to be within or not appear in the note (AND, NOT). + * + * Split by space, quotes are supported: + * - foo bar + * -> searches for notes that contain "foo" and "bar" + * - foo "bar baz" + * -> searches for notes that contain "foo" and "bar baz" + * + * Exclusion is supported: + * - foo -bar + * -> search for notes that contain "foo" but not "bar" + * - foo -"bar baz" + * -> search for notes that contain "foo" but not "bar baz" + * + * @param string $query User-given query string + * + * @return array Array of keyword arrays, grouped by "AND" and "NOT" + */ + public function parse($query) + { + $keywords = array(); + $query = trim($query); + + $groupMap = array( + '+' => 'AND', + '-' => 'NOT', + ); + + $chQuote = null; + $curKeyword = ''; + $group = 'AND'; + foreach (str_split($query) as $char) { + if ($char == '"' || $char == '\'') { + if ($chQuote === null) { + //new quote + $chQuote = $char; + continue; + } else if ($char == $chQuote) { + //quote end + if (strlen($curKeyword)) { + $keywords[$group][] = $curKeyword; + $curKeyword = ''; + } + $chQuote = null; + continue; + } + } else if ($char == ' ' && $chQuote === null) { + if (strlen($curKeyword)) { + $keywords[$group][] = $curKeyword; + $curKeyword = ''; + $group = 'AND'; + } + continue; + } else if ($char == '+' || $char == '-' && $curKeyword == '') { + $group = $groupMap[$char]; + continue; + } + + $curKeyword .= $char; + } + if (strlen($curKeyword)) { + $keywords[$group][] = $curKeyword; + } + return $keywords; + } + +} +?> -- cgit v1.2.3