Hướng dẫn php regex non greedy

I have a string (from a file):

ILX (New for 2013!)

Overview: The least expensive route to Honda's premium-label goodness

Drivetrain: Two four-cylinder engines to choose from as well as a gas-electric hybrid; front-wheel-drive only.

How I get the string:

$writeup = file_get_contents($car_files_path . $manufacture . '/Stories/'.$story);

I want to match the overview line (Overview: The least expensive route to Honda's premium-label goodness). What is the best way to achieve this.

I tried .*\n, but that will match everything and then a new line. Is there a way to make regex non-greedy?

I have tried: preg_match('/^Overview:\s.*$/im', $writeup, $overall_matches) and I don't get any matches

asked Feb 19, 2013 at 21:10

Chris MuenchChris Muench

17.9k69 gold badges204 silver badges352 bronze badges

3

Add ? after the quantifier to make it ungreedy. In this case, your regex would be .*?\n.

To specifically match the line beginning with "Overview: ", use this regex:

/^Overview:\s.*$/im

The m modifier allows ^ and $ to match the start and end of lines instead of the entire search string. Note that there is no need to make it ungreedy since . does not match newlines unless you use the s modifier - in fact, making it ungreedy here would be bad for performance.

answered Feb 19, 2013 at 21:13

9

Summary: in this tutorial, you’ll learn about the regex non-greedy (or lazy) quantifiers that match their preceding elements as few times as possible.

Introduction to the regex non-greedy (or lazy) quantifiers

In regular expressions, the quantifiers have two versions: greedy and non-greedy (or lazy). In the previous tutorial, you learned how greedy quantifiers work.

To turn a greedy quantifier into a non-greedy quantifier, you can append a question mark (?) to it. The following table shows the greedy and non-greedy quantifiers:

Greedy quantifierLazy quantifierMeaning
* *? Match its preceding element zero or more times.
+ +? Match its preceding element one or more times.
? ?? Match its preceding element zero or one time.
{ n } { n }? Match its preceding element exactly n times.
{ n ,} { n ,}? Match its preceding element at least n times.
{ n , m } { n , m }? Match its preceding element from n to m times.

The following example uses the non-greedy quantifier (+?) to match the text within the quotes (""):

$str = 'Home'; $pattern = '/".+?"/'; if (preg_match_all($pattern, $str, $matches)) { print_r($matches[0]); }

Code language: HTML, XML (xml)

Output:

Array ( [0] => "/" [1] => "Go to homepage" )

Code language: PHP (php)

How the non-greedy quantifier (+? ) works.

First, the regex engine searches for a match starting from the first position in the string. Because the regex engine cannot find a match, it continues searching until it finds the first quote ("):

Second, the regex engine finds a match for the rule .+? . However, the non-greedy quantifier +? just matches one time, not multiple times to the end of the string like the greedy quantifier (+). And the regex engine immediately looks at the next rule in the pattern, which matches a quote (“):

Hướng dẫn php regex non greedy

Third, the regex engine repeats the first and second steps starting from the position after the first match and returns the next result:

Finally, the regex engine continues to search till the end of the string:

Summary

  • Append a question mark (?) to a quantifier to turn it into a non-greedy quantifier.
  • A non-greedy quantifer tries to match its preceding element as few times as possible.

Did you find this tutorial useful?