Perl regex matches closest

I am trying to match the last content with the final word.

For example, closest to a dog

"abcbdog"

Must be "bdog"

But instead I get "bcbdog"

How can I match only the last occurrence of "b" before "dog"

Here is my current regex:

/b.*?dog/si 

Thanks!

+4
source share
6 answers

Regexes want to go from left to right, but you want to go from right to left to just cancel your line, change the pattern, and change the match:

 my $search_this = 'abcbdog'; my $item_name = 'dog'; my $find_closest = 'b'; my $pattern = reverse($item_name) . '.*?' . reverse($find_closest); my $reversed = reverse($search_this); $reversed =~ /$pattern/si; my $what_matched = reverse($&); print "$what_matched\n"; # prints bdog 
+7
source

Try the following:

 /b[^b]*dog/si 

Match b , then everything that is not b (including nothing), and then dog .

+4
source

TIMTOWTDI:

This method may even find multiple matches in a string, or it may be optimized if the start or end words are more common. Edit: Zero-width matches are now used to avoid deletion, and then the start and end lines are added.

 #!/usr/bin/env perl use strict; use warnings; use v5.10; #say my $string = 'abcbdog'; my $start = 'b'; my $end = 'dog'; my @found = grep { s/(?<=$end).*// } split( /(?=$start)/, $string ); say for @found; 
+1
source

when you donโ€™t already know what is the last character in front of the dog, it just works:

 my $str = 'abcbdog'; my @r = $str =~ /(.dog)/; print @r; 

prints bdog

0
source

The accepted answer seems a bit complicated if you are just trying to match the closest โ€œbโ€ to the โ€œdogโ€, including the dog, you just need to make your matches before you look for greedy ones. For instance:

 # First example my $string1 = 'abcbdog'; if ( $string1 =~ /.+(b.*dog)/ ) { print $1; # Returns 'bdog' } # Second example, different string, same regex. my $string2 = 'abcbmoretextdog'; if ( $string2 =~ /.+(b.*dog)/ ) { print $1; # Returns 'bmoretextdog' } 

Or am I missing something? If you want to change the captured line according to what you want, just shift the brackets.

0
source

Try this code:

 ~/.* b.*?dog/si 
0
source

All Articles