我正在编写一个搜索词解析器来对搜索令牌进行分类,以便以后进行后期处理。到目前为止,我有这种模式:
/([+])?([\-])?(\"([^\"]+)?\"?|([^\\s]+)?|([^*]+)?)([\\s])?/
采用示例搜索字符串,例如:
c++ +this -only this* +"is a very" "complex example"
我想得到以下结果
G1 G2 G3 G4 G5 G6 G7
c++ c++ [space]
+ +this this [space]
- -only only [space]
this* this * [space]
+ "is a very" is a very [space]
"complex example" complex example [space]
我得到的内容几乎与上述匹配类似,但this*
字词在第5组显示为this*
。
我知道... ([^\\s]+)?|([^*]+)?) ...
部分不正确,但我不知道如何重新制定它。我尝试了几种方法,但似乎没有通过交换子模式等找到一个好的解决方案。
如果有人能给我一些关于如何解决这个问题的提示并且可能使搜索词匹配部分更有效,我会很高兴。
这是我的测试脚本:
<?php
$s = "c++ +this -only this* +\"is a very\" \"complex example\"";
$rc = preg_match_all(
"/([+])?([\-])?(\"([^\"]+)?\"?|([^\\s]+)?|([^*]+)?)([\\s])?/",
$s,
$m);
print_r($m);
?>
非常感谢!
答案 0 :(得分:2)
我不确定为什么要区分G1和G2。这是一种工作模式:
([-+]?)("([^"]+)"|([^\s*]+)(\*?))(\s)?
您的模式存在的问题是您使用的是([^\\s]+)?|([^*]+)?)
。由于test*
将满足选择中的第一个条件,因此永远不会比较第二个选项。
PHP实现将是:
$re = "~([-+]?)(\"([^\"]+)\"|([^\\s*]+)(\\*?))(\\s)?~";
$str = "c++ +this -only this* +\"is a very\" \"complex example\"";
preg_match_all($re, $str, $matches);
使用此模式的缺点是每个单词都有一个空白的G5(表格中为G6)。你可以在角落里使用前瞻,但我不会过分担心。