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