用于解析带有搜索语法的搜索词的正则表达式模式

3
我正在编写一个搜索词解析器,用于分类后续的后处理。目前我有这个模式:
/([+])?([\-])?(\"([^\"]+)?\"?|([^\\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);
?>

非常感谢!

但是在 https://regex101.com/r/lZ6hS8/1 中并没有第四组? - Avinash Raj
请问您想通过这些组实现什么目标?请将组内容写在一行中。 - Avinash Raj
@Avinash:我使用分组来对搜索标记进行分类(实际上,组ID用于设置一些位,例如是否包含或排除术语、短语或通配符术语)。例如,该代码是我用于拼写检查器的C++程序的一部分。 - Andreas W. Wylach
1
你可以从这个链接 https://regex101.com/r/fM9gS2/3 获取一些关于正则表达式的想法。 - Avinash Raj
@Avinash:感谢你的建议!肯定值得尝试。 - Andreas W. Wylach
1个回答

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)。您可以针对特殊情况使用前瞻,但我不会过于担心它。

G1是排除术语,G2是包含术语。G5是标记末尾的空格,这很好。原因是我携带了一个反映每个标记属性的位集。一个小问题:如果我想捕获不仅附加到术语(如G5)的星号,而且整个术语“this*”,我需要改变什么? - Andreas W. Wylach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接