tags:

views:

144

answers:

2

This should be simple but I'm a noob and I can't for the life of me figure it out. I'm trying to use regex to match text inside of special open/close tags: [p2][/p2]

So in this text:

apple [p2]banana[/p2] grape [p2]lemon[/p2]

it should match "banana" and "lemon". The regex I've worked up so far is:

(?<=\[p2\]).+(?=\[\/p2\])

But this is too greedy. It matches starting with the "b" in banana and ends with the "n" in lemon, matching banana[/p2] grape [p2]lemon. How do I just match banana and lemon?

+2  A: 

This should do it:

(?<=\[p2\]).+?(?=\[\/p2\])

I added the question mark to make the quantifier non-greedy.

Franz
thanks for the answer
Jared Henderson
Alternatively, you can specify the `U` modifier to indicate that all quantifiers in the pattern should be considered as non-greedy, e.g. `preg_match('/(?<=\[p2\]).+(?=\[\/p2\])/U', ....` Notice the **capital** `U` character will automatically convert the `+` sign to non-greedy, and a trailing `?` (greediness operator) would cause it to exhibit the behavior you are describing. Worth knowing.See: http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php
Dereleased
@Dereleased: I don't quite understand. What exactly is the difference? Thanks for the comment, though.
Franz
`/U` is overkill in this case, what with there being only one quantifier. But I would avoid using `/U` in any case; it makes your regex less portable (few regex flavors support it) and less readable. People expect quantifiers to be greedy, and have to make a conscious effort to override that expectation. That's a lot easier to do when you're looking at the `?` right next to the quantifier.
Alan Moore
A: 

Instead of using a regex modifier, you can use the standard perl style match modifier and add a ? after + or * to tell that specific portion to be non-greedy. Mentioned above, but specificity can help.

kbenson