$str =~ s/X[^X]*$/X/; #### $str =~ s/(.*X).*/$1/; #### $str =~ s/.*X\K.*//; #### $str =~ /.*X/g and $str =~ s/\G.*//; #### ($str = reverse $str) =~ s/^[^X]+//; $str = reverse $str; #### substr($str, rindex($str, "X")+1) = ""; #### use Benchmark 'cmpthese'; my $str = "alphabet X alphabet" x 100 . "junk at the end" x 10; cmpthese(-5, { # is this the last X? last => sub { my $x = $str; $x =~ s/X[^X]*$/X/ }, # capture up to the last X and replace it with itself capt_repl => sub { my $x = $str; $x =~ s/(.*X).*/$1/ }, # match up to the last X, then remove everything after it rx_rx => sub { my $x = $str; $x =~ /.*X/g and $x =~ s/\G.*// }, # reverse, remove up to first X, reverse sexeger => sub { my $x = $str; ($x = reverse $x) =~ s/^[^X]+//; $x = reverse $x; }, # find the last X, remove everything after it substr => sub { my $x = $str; substr($x, rindex($x, "X")+1) = "" }, }); __END__ Rate last sexeger capt_repl rx_rx substr last 6398/s -- -84% -84% -90% -97% sexeger 39625/s 519% -- -4% -37% -83% capt_repl 41274/s 545% 4% -- -35% -82% rx_rx 63380/s 891% 60% 54% -- -73% substr 230796/s 3507% 482% 459% 264% -- #### cmpthese(-5, { last => sub { my $x = $str; $x =~ s/([A-Z])[^A-Z]*$/$1/ }, capt_repl => sub { my $x = $str; $x =~ s/(.*[A-Z]).*/$1/ }, rx_rx => sub { my $x = $str; $x =~ /.*[A-Z]/g and $x =~ s/\G.*// }, sexeger => sub { my $x = $str; ($x = reverse $x) =~ s/^[^A-Z]+//; $x = reverse $x; }, }); __END__ Rate last capt_repl rx_rx sexeger last 5591/s -- -82% -86% -86% capt_repl 30599/s 447% -- -21% -24% rx_rx 38948/s 597% 27% -- -3% sexeger 40049/s 616% 31% 3% -- #### /* C code */ printf("%s", strpbrk("breakfast", "aeiou")); /* prints: eakfast */ #### if ("breakfast" =~ /[aeiou]/) { $x = substr("breakfast", $-[0]); } #### # crindex is char-class-based rindex() use String::Index 'crindex'; cmpthese(-5, { last => sub { my $x = $str; $x =~ s/([A-Z])[^A-Z]*$/$1/ }, capt_repl => sub { my $x = $str; $x =~ s/(.*[A-Z]).*/$1/ }, rx_rx => sub { my $x = $str; $x =~ /.*[A-Z]/g and $x =~ s/\G.*// }, sexeger => sub { my $x = $str; ($x = reverse $x) =~ s/^[^A-Z]+//; $x = reverse $x; }, crindex => sub { my $x = $str; substr($x, crindex($x, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")+1) = ""; }, }); __END__ Rate last capt_repl rx_rx sexeger crindex last 5581/s -- -82% -85% -86% -90% capt_repl 30606/s 448% -- -20% -23% -44% rx_rx 38194/s 584% 25% -- -4% -30% sexeger 39594/s 609% 29% 4% -- -28% crindex 54829/s 882% 79% 44% 38% --