在数学表达php中删除周围的括号



我正在尝试弄清楚如何使用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);

实时演示

最新更新