From 0da3a233d6a155a67db1b05383bbacb1015c69eb Mon Sep 17 00:00:00 2001 From: rurban Date: Thu, 4 Jun 2009 08:12:59 +0000 Subject: [PATCH] Add phrase_starts_with ^S != S* ^x matches only beginning of phrase, not of word x* matches any word beginning with x git-svn-id: svn://svn.code.sf.net/p/phpwiki/code/trunk@6853 96ab9672-09ca-45d6-a79d-3d69d39ca109 --- lib/TextSearchQuery.php | 40 +++++++++++++++++++++++++++++++++----- lib/plugin/TitleSearch.php | 2 ++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/TextSearchQuery.php b/lib/TextSearchQuery.php index e572644be..1c992b011 100644 --- a/lib/TextSearchQuery.php +++ b/lib/TextSearchQuery.php @@ -13,8 +13,11 @@ * 'word' OR the substring 'page'. *
auto-detect regex hints, glob-style or regex-style, and converts them * to PCRE and SQL matchers: - *
"^word$" => EXACT(word) - *
"^word" => STARTS_WITH(word) + *
"^word$" => EXACT(phrase) + *
"^word" => STARTS_WITH(phrase) + *
"word$" => ENDS_WITH(phrase) + *
"^word" ... => STARTS_WITH(word) + *
"word$" ... => ENDS_WITH(word) *
"word*" => STARTS_WITH(word) *
"*word" => ENDS_WITH(word) *
"/^word.* /" => REGEX(^word.*) @@ -651,7 +654,7 @@ class TextSearchQuery_node } /** - * A word. exact or substring? + * A word. Exact or substring? */ class TextSearchQuery_node_word extends TextSearchQuery_node @@ -678,6 +681,7 @@ extends TextSearchQuery_node { function regexp() { return '(?=.*)'; } function sql() { return '%'; } } + class TextSearchQuery_node_starts_with extends TextSearchQuery_node_word { var $op = "STARTS_WITH"; @@ -686,6 +690,12 @@ extends TextSearchQuery_node_word { function sql () { return $this->_sql_quote($this->word).'%'; } } +// ^word: full phrase starts with +class TextSearchQuery_phrase_starts_with +extends TextSearchQuery_node_starts_with { + function regexp() { return '(?=^' . preg_quote($this->word, '/') . ')'; } +} + class TextSearchQuery_node_ends_with extends TextSearchQuery_node_word { var $op = "ENDS_WITH"; @@ -694,6 +704,12 @@ extends TextSearchQuery_node_word { function sql () { return '%'.$this->_sql_quote($this->word); } } +// word$: full phrase ends with +class TextSearchQuery_phrase_ends_with +extends TextSearchQuery_node_ends_with { + function regexp() { return '(?=' . preg_quote($this->word, '/') . '$)'; } +} + class TextSearchQuery_node_exact extends TextSearchQuery_node_word { var $op = "EXACT"; @@ -935,7 +951,7 @@ class TextSearchQuery_Parser * /"[^"]*"/ WORD * /'[^']*'/ WORD * - * ^WORD STARTS_WITH + * ^WORD TextSearchQuery_phrase_starts_with * WORD* STARTS_WITH * *WORD ENDS_WITH * ^WORD$ EXACT @@ -972,6 +988,12 @@ class TextSearchQuery_Parser else return false; } + if ($is_toplevel and count($list) == 1) { + if ($this->lexer->query_str[0] == '^') + return new TextSearchQuery_phrase_starts_with($list[0]->word); + else + return $list[0]; + } return new TextSearchQuery_node_and($list); } @@ -1038,7 +1060,14 @@ class TextSearchQuery_Parser if ( $accept & $const and (($word = $this->lexer->get($const)) !== false)) { - $classname = "TextSearchQuery_node_".strtolower($tok); + // phrase or word level? + if ($tok == 'STARTS_WITH' and $this->lexer->query_str[0] == '^') + $classname = "TextSearchQuery_phrase_".strtolower($tok); + elseif ($tok == 'ENDS_WITH' and + string_ends_with($this->lexer->query_str,'$')) + $classname = "TextSearchQuery_phrase_".strtolower($tok); + else + $classname = "TextSearchQuery_node_".strtolower($tok); return new $classname($word); } } @@ -1051,6 +1080,7 @@ class TextSearchQuery_Lexer { $regex=TSQ_REGEX_AUTO) { $this->tokens = $this->tokenize($query_str, $case_exact, $regex); + $this->query_str = $query_str; $this->pos = 0; } diff --git a/lib/plugin/TitleSearch.php b/lib/plugin/TitleSearch.php index 4a5b90001..a2cfe7099 100644 --- a/lib/plugin/TitleSearch.php +++ b/lib/plugin/TitleSearch.php @@ -77,6 +77,8 @@ extends WikiPlugin return HTML(); } + // ^S != S* ^ matches only beginning of phrase, not of word. + // x* matches any word beginning with x $query = new TextSearchQuery($args['s'], $args['case_exact'], $args['regex']); $pages = $dbi->titleSearch($query,$args['sortby'],$args['limit'],$args['exclude']); -- 2.45.0