Jeśli nie absolutnie trzeba użyć regex,
użycie
rozważyć użycie Perl Text::Balanced usunąć nawias.
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;
}
Może myślisz: "Dlaczego to wszystko, gdy regex wykonuje lewę w jednej linii?"
$filename =~ s/\([^}]*\)//;
Tekst :: Otwory zagnieżdżone zagnieżdżone nawiasy. Tak więc $filename = 'foo_(bar(baz)buz)).foo'
zostanie poprawnie wyodrębniony. Oferowane tu rozwiązania oparte na regex nie będą działać w tym łańcuchu. Ten zatrzyma się przy pierwszym zamknięciu, a drugi zje wszystkie.
$ filename = ~ s/([^}] *) //; # zwraca 'foo_buz)). Foo'
$ filename = ~ s /(.*)//; # Zwraca „foo_.foo” „foo _) foo”
# tekst wyważony przykład zwraca
Jeśli któryś z regex zachowań jest akceptowalna, należy użyć wyrażenia regularnego - ale dokumentują ograniczenia i założenia są wykonane .Kod
Czy jesteś pewien, że "extra_descriptor" nie może zawierać znaku ")"? Jeśli to może problem staje się znacznie trudniejszy ... – dmckee
@dmckee: Jest trudniej, jeśli pareny mogą być * zagnieżdżone *, ale jeśli chcesz po prostu pozbyć się wszystkiego między pierwszym ("i" ostatnim), to jest niewiele trudniej: po prostu użyj chciwego ". *" zamiast ". *?". –
@j_random_hacker Masz rację, jest o wiele trudniej, ponieważ zagnieżdżone nawiasy nie mogą zostać rozpoznane za pomocą FSM (musisz śledzić poziom zagnieżdżenia, który jest nieograniczony), a więc nie przez wyrażenie regularne. Aby było możliwe, musisz ograniczyć się do ograniczonego poziomu zagnieżdżania. – skyking