Why doesn't my non-greedy Perl regex match anything?

I thought I understood Perl RE to a reasonable extent, but this puzzles me:

#!/usr/bin/perl use strict; use warnings; my $test = "'some random string'"; if($test =~ /\'?(.*?)\'?/) { print "Captured $1\n"; print "Matched $&"; } else { print "What?!!"; } 

prints

Captured
Agreed '

It seems that he compared the ending to β€œone” and so did not capture anything.
I would expect that it will correspond to everything, or if it is not completely greedy, nothing at all (since everything is an optional coincidence).
This between behavior puzzles me, can someone explain what is happening?

+4
source share
5 answers

\'? at the beginning and at the end means with greed 0 or 1 apostrophes. (As another poster pointed out, in order to make it inanimate, it must be \'?? )

.*? in the middle means matching 0 or more characters without greed.

Perl's regex engine will look at the first part of a line. He will be consistent with the beginning, but he does it with greed, so he raises the first apostrophe. Then it corresponds to not greedy (as little as possible is required), and then an optional apostrophe. This corresponds to an empty string.

+14
source

I think you mean something like:

 /'(.*?)'/ // matches everything in single quotes 

or

 /'[^']*'/ // matches everything in single quotes, but faster 

Sing quotes should not be avoided, AFAIK.

+3
source

pattern? greedy, if you want it to not be greedy, you have to say pattern?? :

 #!/usr/bin/perl use strict; use warnings; my $test = "'some random string'"; if($test =~ /\'?(.*?)\'?/) { print "Captured [$1]\n"; print "Matched [$&]\n"; } if($test =~ /\'??(.*?)\'??/) { print "Captured [$1]\n"; print "Matched [$&]\n"; } 

from perldoc perlre:

The following standard quantifiers are recognized:

 * Match 0 or more times + Match 1 or more times ? Match 1 or 0 times {n} Match exactly n times {n,} Match at least n times {n,m} Match at least n but not more than m times 

By default, the quantized subpattern is greedy, that is, it will match as many times as possible (given the specific starting location), while still allowing the rest of the template to match. If you want to match the minimum number of times, follow the quantifier with "?". Note that the values ​​do not change, just "greed":

 *? Match 0 or more times +? Match 1 or more times ?? Match 0 or 1 time {n}? Match exactly n times {n,}? Match at least n times {n,m}? Match at least n but not more than m times 
+2
source

Beware of making all elements of your regular expression optional (i.e. all elements will be quantified with * or?). This allows the Perl regular expression engine to match as much as it wants (even nothing), but is still considered successful.

I suspect you want

 /'(.*?)'/ 
+1
source

I would say that the closest answer to what you are looking for is

 /'?([^']*)'?/ 

So, "get a single quote, if there is one," "get everything and everything that is not one quote," "get the last single quote, if there is one."

If you want to combine β€œdon't do this,” but who still uses the apostrophe in one quotation mark (and leaves it for a long time)? :)

+1
source

All Articles