我需要解析一个包含一些以递归方式放置的括号的字符串,但是我在确定括号的优先级时遇到了麻烦。 例如,我有字符串
$truth = "((A^¬B)->C)";
,我需要返回括号之间的内容。我已经使用以下正则表达式完成了此操作:
preg_match_all("~\((.*?)\)~", $truth, $str);
但是问题在于它返回第一个“(”和第一个“)”之间的值,即
(A ^¬B
相反,我需要它“知道”括号正确关闭的位置,以便返回
(A ^¬B)-> C
如何按照优先顺序退回此物品?谢谢!
答案 0 :(得分:3)
对于您的示例字符串,类似的内容将递归给您括号的内容。通过在正则表达式的两端使用^[^(]*
和[^)]*$
来强制匹配的括号成为最外面的一对。
$truth = "((A^¬B)->C)";
while (strpos($truth, '(') !== false) {
preg_match("~^[^(]*\((.*?)\)[^)]*$~", $truth, $str);
$truth = $str[1];
echo "$truth\n";
}
输出
(A^¬B)->C
A^¬B
但是请注意,这将无法正确解析诸如(A+B)-(C+D)
之类的字符串。如果您的情况适合您,this answer可能会有所帮助。
答案 1 :(得分:3)
您当前遇到的主要问题是?
的非贪婪位。如果将其更改为仅.+
贪婪,它将满足您的需求。
$truth = "((A^¬B)->C)";
preg_match('/\(.+\)/', $truth, $match);
输出
(A^¬B)->C
如果要匹配内部对,则可以使用递归子模式:
$truth = "((A^¬B)->C)";
preg_match('/\(([^()]+|(?0))\)/', $truth, $match);
输出
A^¬B
如果您需要走得更远,则可以创建一个词法分析器/解析器。我这里有一些例子: