Tengo dos tipos de cadenas en un texto:
a(bc)de(fg)h
a(bcd(ef)g)h
Necesito obtener texto entre paréntesis de primer nivel. En mi ejemplo esto es:
antes de Cristo
fg
bcd(ef)g
Traté de usar la siguiente expresión regular /\((.+)\)/ con el indicador Ungreedy (U):
antes de Cristo
fg
bcd(ef
Y sin ella:
bc)de(fg
bcd(ef)g
Ambas variantes no hacen lo que necesito. Tal vez alguien sabe cómo resolver mi problema?
Use el patrón recursivo PCRE para hacer coincidir las subcadenas entre paréntesis anidados:
$str = "a(bc)de(fg)h some text a(bcd(ef)g)h "; preg_match_all("/\((((?>[^()]+)|(?R))*)\)/", $str, $m); print_r($m[1]);La salida:
Array ( [0] => bc [1] => fg [2] => bcd(ef)g ) \( ( (?>[^()]+) | (?R) )* \)
Primero coincide con un paréntesis de apertura. Luego, coincide con cualquier número de subcadenas que pueden ser una secuencia sin paréntesis o una coincidencia recursiva del patrón en sí (es decir, una subcadena correctamente entre paréntesis). Finalmente, hay un paréntesis de cierre.
Precauciones técnicas:
Si hay más de 15 paréntesis de captura en un patrón, PCRE tiene que obtener memoria adicional para almacenar datos durante una recursión, lo que hace mediante el uso de pcre_malloc, y luego lo libera a través de pcre_free. Si no se puede obtener memoria, guarda datos solo para los primeros 15 paréntesis de captura, ya que no hay forma de dar un error de falta de memoria dentro de una recursión.
Por favor puedes intentar eso:
preg_match("/\((.+)\)/", $input_line, $output_array);Pruebe este código en http://www.phpliveregex.com/
Regex: \((.+)\) Input: a(bcd(eaerga(er)gaergf)g)h Output: array(2 0 => (bcd(eaerga(er)gaergf)g) 1 => bcd(eaerga(er)gaergf)g )