Si no absolutamente necesario utilizar una expresión regular,
uso
considerar el uso de Perl Text::Balanced para eliminar los paréntesis.
use Text::Balanced qw(extract_bracketed);
my ($extracted, $remainder, $prefix) = extract_bracketed($filename, '()', '[^(]*');
{ no warnings 'uninitialized';
$filename = (defined $prefix or defined $remainder)
? $prefix . $remainder
: $extracted;
}
Usted puede estar pensando, "¿Por qué hacer todo esto cuando una expresión regular hace el truco en una línea?"
$filename =~ s/\([^}]*\)//;
Text :: Balanced handles nested parenthesis. Por lo tanto, $filename = 'foo_(bar(baz)buz)).foo'
se extraerá correctamente. Las soluciones basadas en expresiones regulares que se ofrecen aquí fallarán en esta cadena. El uno se detendrá en la primera reunión de padres, y el otro se los comerá a todos.
$ filename = ~ s/([^}] *) //; # devuelve 'foo_buz)). Foo'
$ filename = ~ s /(.*)//; # devuelve 'foo_.foo' 'foo _) foo'
# texto equilibrado ejemplo retornos
Si cualquiera de los comportamientos de expresiones regulares es aceptable, utilice una expresión regular - pero documentar las limitaciones y los supuestos que se hizo .código
¿Estás seguro de que el "extra_descriptor" no puede incluir un ")"? Si puede, el problema se vuelve mucho más difícil ... – dmckee
@dmckee: es más difícil si los pares pueden * anidar *, aunque si solo quieres deshacerte de todo entre el primero '(' y el último ')' es no mucho más difícil: simplemente use un codicioso '. *' en lugar de '. *?'. –
@j_random_hacker Estás en lo correcto, es mucho más difícil ya que los paréntesis anidados no se pueden reconocer con un FSM (tienes que hacer un seguimiento del nivel de anidación que es ilimitado) y por lo tanto no con una expresión regular. Para que sea posible, debe restringirse a un nivel limitado de anidación. – skyking