/ / Jak mogę dopasować wszystko, co jest po ostatnim wystąpieniu znaku w wyrażeniu regularnym Perla? - regex, perl

Jak mogę dopasować wszystko, co jest po ostatnim wystąpieniu jakiegoś znaku w wyrażeniu regularnym perla? - regex, perl

Na przykład zwróć część ciągu po ostatniej x w axxxghdfx445 (powinien wrócić 445).

Odpowiedzi:

16 dla odpowiedzi nr 1
my($substr) = $string =~ /.*x(.*)/;

Z perldoc perlre:

Domyślnie określony ilościowo wzór jest „zachłanny”, to znaczy będzie pasował tyle razy, ile to możliwe (przy określonej lokalizacji początkowej) podczas nadal pozwalając na dopasowanie pozostałej części wzoru.

Dlatego .*x dopasuje do ostatniego wystąpienia x.


7 dla odpowiedzi nr 2

Najprostszym sposobem byłoby użycie /([^x]*)$/


5 dla odpowiedzi nr 3

pierwsza odpowiedź jest dobra, ale mówiąc o „czymś, co nie zawiera” ... lubię używać wyrażenia regularnego, które „pasuje” do niego

my($substr) = $string =~ /.*x([^x]*)$/;

bardzo przydatne w niektórych przypadkach


3 dla odpowiedzi № 4

Jeszcze inny sposób na zrobienie tego. To nie jest tak proste jak pojedyncze wyrażenie regularne, ale jeśli optymalizujesz szybkość, to podejście będzie prawdopodobnie szybsze niż cokolwiek używającego wyrażenia regularnego, w tym split.

my $s     = "axxxghdfx445";
my $p     = rindex $s, "x";
my $match = $p < 0 ? undef : substr($s, $p + 1);

3 dla odpowiedzi № 5

Dziwi mnie, że nikt nie wspomniał o specjalnej zmiennej, która to robi, $": "$""zwraca wszystko po dopasowanym ciągu. (perldoc perlre)

my $str = "axxxghdfx445";
$str =~ /x/;

# $" contains "445";
print $";

Istnieje jednak koszt (moje podkreślenie):

OSTRZEŻENIE: Gdy Perl zobaczy, że potrzebujesz jednego z $ &, „$", or "$"" anywhere in the program, it has to provide them for every pattern match. This may substantially slow your program. Perl uses the same mechanism to produce $1, $2, etc, so you also pay a price for each pattern that contains capturing parentheses. (To avoid this cost while retaining the grouping behaviour, use the extended regular expression "(?: ... )" instead.) But if you never use $&, "$”lub„ $ ””, a następnie wzory bez przechwytywanie nawiasów nie będzie karane. Unikaj więc $ &, „$” i „$”, jeśli możesz, ale jeśli nie możesz (i niektóre algorytmy naprawdę doceniam ich), gdy raz ich użyjesz, używaj ich do woli, ponieważ już zapłaciłeś cenę. Od 5.005 $ i nie jest tak kosztowne jak pozostałe dwa.

Ale poczekaj, jest więcej! Dostajesz dwóch operatorów za cenę jednego, działaj TERAZ!

Aby obejść ten problem, Perl 5.10.0 przedstawia „$ {^ PREMATCH}”, „$ {^ MATCH}” i „$ {^ POSTMATCH}”, które są równoważne na „$”, $ i „$”, z tym wyjątkiem, że są tylko gwarantowane zdefiniowane po udanym dopasowaniu wykonanym za pomocą „/ p” (zachowaj) modyfikator. Zastosowanie tych zmiennych nie powoduje globalizacji kara wydajnościowa, w przeciwieństwie do ich znaków interpunkcyjnych na kompromisie, który musisz powiedzieć Perlowi, kiedy chcesz ich użyć.

my $str = "axxxghdfx445";
$str =~ /x/p;

# ${^POSTMATCH} contains "445";
print ${^POSTMATCH};

Pokornie poddam się, że ta droga jest najlepszai najbardziej bezpośredni podejście w większości przypadków, ponieważ nie wymaga to robienia specjalnych rzeczy z twoją konstrukcją wzoru, aby odzyskać część postmatchu i tam nie ma negatywnego wpływu na wydajność.


2 dla odpowiedzi № 6

najprostszym sposobem nie jest wyrażenie regularne, ale prosty split () i uzyskanie ostatniego elementu.

$string="axxxghdfx445";
@s = split /x/ , $string;
print $s[-1];

1 dla odpowiedzi № 7

Wyrażenie regularne : /([^x]+)$/ #assuming x is not last element of the string.