A string may contain non-number in braces which needs to be deleted. Input can be multiline too, for example :
input:
# (1437)
# {19} (917) (1437)
# {19} (1437) [1449] [2474] [2098] [1351] [508] [969]( MONDAY) [sunday]
desired output:
# (1437)
# {19} (917) (1437)
# {19} (1437) [1449] [2474] [2098] [1351] [508] [969]
However the below regex instead of removing just ( MONDAY) [sunday] removes the last line completely.
$re = '/^(#\h*)((\[\d ]|\{\d }|\(\d \))(?:\h (?3))*)$/m';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
echo implode("\n", array_map(fn($x) => $x[1] . implode(' ', array_unique(explode(' ', $x[2]))), $matches));
CodePudding user response:
In php (PCRE) flavor you may use this regex with conditional construct:
(?:(\()|({)|\[)\D*(?(1)\)|(?(2)}|]))\s*
RegEx Details:
(?:: Start non-capture group(\(): Match(and capture in group #1|: OR({): Match{and capture in group #2|: OR\[: Match a[
): non-capture group\D*: Match 0 or more non-digits(?(1)\): If group #1 is present then match)|: OR(?(2)}|]): If group #2 is present then match}else match]
): End of conditional construct\s*: Match 0 or more whitespaces
Code:
$r = preg_replace('/(?:(\()|({)|\[)\D*(?(1)\)|(?(2)}|]))\s*/', '', $s);
A bit more efficient version of above regex (avoids backtracking):
(?:(\()|({)|\[)(?(1)[^)\d]*\)|(?(2)[^}\d]*}|[^]\d]*]))\s*
