CluelessNoob
CluelessNoob

Reputation: 696

PHP RegEx capturing a bigger match ignoring a smaller match

Here is my code:

<?php
    $sentence = "{To|Preposition}{talk|Verb}{here|Place}.";

    $pattern = "/{(.*)\|(.*)}/";

    preg_match($pattern, $sentence, $match_arr);

    $match = $match_arr[0];

    $a = $match_arr[1];
    $b = $match_arr[2];

    echo "$match<br /><br />$a<br /><br />$b";
?>

The output is:

{To|Preposition}{talk|Verb}{here|Place}

To|Preposition}{talk|Verb}{here

Place

But I want it to be like this:

{To|Preposition}

To

Preposition

So basically, instead of capturing the first match, it just captures the entire sentence (which is technically a bigger match). How can I change the pattern to actually capture the first smaller match to get the desired result?

Thanks.

Upvotes: 1

Views: 85

Answers (3)

hwnd
hwnd

Reputation: 70722

You need to follow .* with a ? for a non-greedy match.

$pattern = "/{(.*?)\|(.*?)}/";

Which will output the following.

{To|Preposition}

To

Preposition

See Working demo

Upvotes: 4

WizKid
WizKid

Reputation: 4908

Change (.*) to ([^|]*) then it will match every character except |

Upvotes: 0

Sean Johnson
Sean Johnson

Reputation: 5607

You need to use an ungreedy match for all subgroups.

"/{(.*)\|(.*)}/U";

This will make the pattern match the least amount of characters possible to still satisfy the pattern. You're getting the results you're getting because the pattern /{(.*)\|(.*)}/ is matching from the opening brace all the way to the closing one.

Upvotes: 2

Related Questions