2017-06-26 31 views
1

我想弄清楚,如何使用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; 
} 
+1

請給我們看看你現在試過什麼。喲去哪個方法去除括號?然後社區會幫助你。你可以用正則表達式,或者字符串提取或者或者... –

+0

用正則表達式,你可以嘗試[類似這個demo的東西](https://eval.in/822350)。 –

+0

@bobblebubble:這是可能性,但不是使用'while'和'preg_match',而應該使用'do ... while'和'preg_replace'的count參數。 –

回答

0
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; 
} 
0

怎麼樣一個班輪正則表達式的解決方案:

$re = "~(?|\({2,}". ($p = "(\(((?:[^()]*|(?1))*)\))") ."\){2,}|^(((\([^()]+\))+))$|$p)~"; 
echo preg_replace($re, '$2', $str); 

Live demo

+0

你也在演示中放置了一個不平衡的'(((((A + B)+ C))'樣本, – revo

+0

不要把這個考慮在內,這是一個錯字。*(必須是' ((((A + B))+ C))')* –

3

隨着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 
) 
+0

這個集羣'(\)\ 2?+)''值得單獨加票。 – revo

+1

@revo:謝謝,但說實話,它來自Qtax答案:https://stackoverflow.com/questions/17039670/vertical-regex-matching-in-an-ascii-image –