我正在尝试弄清楚如何使用php中的数学表达式删除周围的括号。
某些情况是:
(a b((b c(应保持相同的
((((((((a(((((((应获得
((A (B C((应获得A*(B C(
(((((((((b c(*a(((((应获得(b c(*a
在任何情况下,我都找不到正确的解决方案。使用诸如分布属性之类的数学规则是没有选项的。
我不是在寻找副本和贴花算法,而只是适合我所有情况的标准。这是最新的尝试,我尝试了等不同的方法,但我没有弄清楚。
function removeSurroundingBrackets($str)
{
$res=$str;
if(strcmp($res[0],'(')===0 && strcmp($res[strlen($res)-1],')')===0)
{
$firstOther=0;
for(; $firstOther<strlen($str);$firstOther++)
{
if(strcmp($str[$firstOther],'(')!==0)
break;
}
$removableCount=0;
$removableCount=substr_count($str,')',$firstOther)-substr_count($str,'(',$firstOther);
}
return substr($str,$removableCount,-$removableCount);
}
编辑:我找到了一个解决方案:
function removeSurroundingBrackets($str)
{
$res=$str;
while(strcmp($res[0],'(')===0 && strcmp($res[strlen($res)-1],')')===0)
{
if($this->checkBrackets(substr($res,1,-1)))
$res=substr($res,1,-1);
else
return $res;
}
return $res;
}
function checkBrackets($str)
{
$currdepth=0;
foreach(str_split($str) as $char)
{
if(strcmp($char,')')===0)
{
if($currdepth<=0)
return false;
else
$currdepth--;
}
else if(strcmp($char,'(')===0)
$currdepth++;
}
return true;
}
with preg_match
:
$pattern = '~A(?:((?=([^()]*(?:((?1))[^()]*)*)()2?+)z))*K(?(1)1|.*)~';
if ( preg_match($pattern, $str, $m) )
echo $m[0], PHP_EOL;
这个想法是在字符串开始时消耗括号,只要它们是最外面的括号。为确保它们是最外层的括号,您需要检查其中是否总是有一个平衡的表达。
要消耗/计算这些最外层的括号,我使用此设计:
A # from the start of the string
(?: # an eventually repeated non-capturing group
(
(?= # a lookahead to check if the corresponding closing parenthesis exists
([^()]*(?:((?1))[^()]*)*) # balanced expression inside
( ) 2?+ ) # capture group grows at each non-capturing group repetition
z # anchored at the end of the string
)
)* # since the quantifier is greedy, it will consume all opening parenthesis
然后,您只需要使用K
从匹配结果中删除这些括号,并测试捕获组1是否存在:
K
(?(?1) # if the capture group 1 exists
1 # match its content
| # else
.* # match all the string
)
function removeSurroundingBrackets($str)
{
$res=$str;
while(strcmp($res[0],'(')===0 && strcmp($res[strlen($res)-1],')')===0)
{
if($this->checkBrackets(substr($res,1,-1)))
$res=substr($res,1,-1);
else
return $res;
}
return $res;
}
function checkBrackets($str)
{
$currdepth=0;
foreach(str_split($str) as $char)
{
if(strcmp($char,')')===0)
{
if($currdepth<=0)
return false;
else
$currdepth--;
}
else if(strcmp($char,'(')===0)
$currdepth++;
}
return true;
}
单线正则态度解决方案:
$re = "~(?|({2,}". ( $p = "((((?:[^()]*|(?1))*)))" ) ."){2,}|^(((([^()]+))+))$|$p)~";
echo preg_replace($re, '$2', $str);
实时演示