[英]parse search string
我有搜索字符串,类似于以下所示:
energy food "olympics 2010" Terrorism OR "government" OR cups NOT transport
并且我需要使用PHP5进行解析,以检测内容是否属于以下任何集群:
这些是我设定的规则:
因此,最终结果应类似于以下内容:
AllWords: (energy, food, "olympics 2010")
AnyWords: (terrorism, "government", cups)
NotWords: (Transport)
什么是做到这一点的好方法?
如果要使用Regex进行此操作,请注意,您的解析将在愚蠢的用户输入(用户,而不是input =)上中断。
我会尝试以下正则表达式。
非字词:
(?<=NOT\s)\b((?!NOT|OR)\w+|"[^"]+")\b
AllWords:
(?<!OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?!\s+OR)
AnyWords:好吧..其余的。 =)它们并不是那么容易发现,因为我不知道如何在正则表达式中加上“或”或“或”。 也许您可以加入三个正则表达式的结果
(?<=OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?!\s+OR)
(?<=OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?=\s+OR)
(?<!OR\s)\b((?!NOT|OR)\w+|"[^"]+")\b(?=\s+OR)
问题:这些要求修饰词和表达式之间恰好有一个空格。 PHP仅支持lookbehinds来修复长度表达式,所以抱歉,我看不到任何解决方法。 您可以只使用\\b(\\w+|"[^"]+")\\b
拆分输入,然后手动解析结果数组。
这是一个很好的例子,说明了测试优先驱动的方法如何帮助您找到解决方案。 它可能不是最好的,但是编写测试可以使您信心十足地进行重构,并立即查看是否破坏了任何现有测试。 无论如何,您可以设置一些测试,例如:
public function setUp () {
$this->searchParser = new App_Search_Parser();
}
public function testSingleWordParsesToAllWords () {
$this->searchParser->parse('Transport');
$this->assertEquals(
$this->searchParser->getAllWords(),
array('Transport')
);
$this->assertEquals($this->searchParser->getNotWords(), array());
$this->assertEquals($this->searchParser->getAnyWords());
}
public function testParseOfCombinedSearchString () {
$query = 'energy food "olympics 2010" Terrorism ' .
'OR "government" OR cups NOT transport';
$this->searchParser->parse($query);
$this->assertEquals(
$this->searchParser->getAllWords(),
array('energy', 'food', 'olympics 2010')
);
$this->assertEquals(
$this->searchParser->getNotWords(),
array('Transport')
);
$this->assertEquals(
$this->searchParser->getAnyWords(),
array( 'terrorism', 'government', 'cups')
);
}
其他好的测试包括:
testParseTwoWords
testParseTwoWordsWithOr
testParseSimpleWithNot
testParseInvalid
testParseEmpty
然后,一个接一个地编写测试,并编写一个通过测试的简单解决方案。 然后重构并使其正确,然后再次运行以查看您仍然通过了测试。 测试通过并重构代码后,请编写下一个测试并重复该过程。 发现特殊情况后添加更多测试,并重构代码,使其通过所有测试。 如果您破坏测试,请备份并重新编写代码(而不是测试!),使其通过。
至于如何解决此问题,请查看preg_match , strtok或依靠循环遍历字符串添加标记。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.