Home > Net >  Regular expression to match and remove unclosed parenthesis
Regular expression to match and remove unclosed parenthesis

Time:11-04

I have a couple of strings I'd like to remove unclosed brackets such as ( or [

"A Pro Webcam ((Good text) [[Good Text] more texts"

"Text (Example (Good text) [Good Text] more texts"

I have tried using this with php with no luck

\((?:[^)(]*(?R)?)* \)

CodePudding user response:

You can use

(?:(\((?:[^()]  |(?1))*\))|(\[(?:[^][]  |(?2))*]))(*SKIP)(*F)|[][()]

See the regex demo. Replace with an empty string.

Details:

  • (?:(\((?:[^()] |(?1))*\))|(\[(?:[^][] |(?2))*]))(*SKIP)(*F) - a string between paired ( and ) or between [ and ]
  • | - or
  • [][()] - a [, ], ( or ).

CodePudding user response:

Match pairs of ( and ) and [ and ] using a stack. If there is a mismatch in such a pair of characters OR if the characters are not available(meaning hanging closed parentheses), collect all such guys in array to be skipped later when creating a clean string.

<?php

function filterUnmatchedParentheses($string){
  $opened = [];
  $unOpened = [];
  $skipIdxs = [];
  $length = strlen($string);
  
  for($i = 0; $i < $length;   $i){
    if($string[ $i ] === '(' || $string[ $i ] === '['){
      $opened[] = $i;
    }else if($string[ $i ] === ')' || $string[ $i ] === ']'){
      $matchFound = false;
      while(count($opened) > 0){
        $idx = array_pop($opened);
        $char = $string[ $idx ];
        if($char == '(' && $string[ $i ] === ')' || $char == '[' && $string[ $i ] === ']'){
          $matchFound = true;
          break;
        }
        $skipIdxs[] = $idx;
      }
      
      if(!$matchFound){
        $unOpened[] = $i;
      }
    }
  }
  
  $skipIdxs = array_flip(array_merge($skipIdxs, $opened, $unOpened));
  
  $res = "";
  
  for($i = 0; $i < $length;   $i){
    if(isset($skipIdxs[ $i ])) continue;
    $res .= $string[ $i ];
  }
  
  return $res;
}

Online Demo

  • Related