tags:

views:

63

answers:

3

I'm using preg_match_all to get the quoted users from a post on a forum like so:

    preg_match_all('/quote author=(.*) link=/', $post, $quotedUsers);

The $post string will typically be something like:

[quote author=John link=topic=1234.msg123456#msg123456 date=1234567890]Lorem ipsum dolor sit amet[/quote]
Lorem ipsum dolor sit amet consectetur elit...

The preg_match_all function works fine when only one user is quoted, and returns something like:

Array
(
    [0] => Array
        (
            [0] => quote author=John link=
        )

    [1] => Array
        (
            [0] => John
        )

)

My code loops through each $quotedUsers[1] to get the usernames, and I thought everything was fine. Except, when two users are quoted, it looks more like this:

Array
(
    [0] => Array
        (
            [0] => quote author=Bob link=topic=1234.msg123456#msg13456 date=1234567890]Lorem ipsum dolor sit amet[/quote]

[quote author=John link=
        )

    [1] => Array
        (
            [0] => Bob link=topic=1234.msg123456#msg13456 date=1234567890]Lorem ipsum dolor sit amet[/quote]

[quote author=John
        )

)

What is going on and how do I fix this? I thought preg_match_all would just put all of the usernames into the $quotedUsers[1] array.

A: 

On your regex you have to make * not greedy

'/quote author=(.*?) link=/'

Just have to add a ? after *

Viper_Sb
A: 

Make the * non-greedy:

/quote author=(.*?) link=/

This will match any character until the next ) found. Otherwise it will match as many characters as possible (meaning it will match up to the last ) found).

More about this at Repetition with Star and Plus

Felix Kling
A: 

The problem is that your current RegExp, with the .* is being greedy and grabbing too much content.

preg_match_all('\[quote author\=([^\]]+) link\=', $post, $quotedUsers);

Should do you.

Amended: Hopefully, usernames will not feature a square bracket...

Lucanos
Won't that stop at spaces? Usernames can have spaces and symbols.
katoth
Lucanos
If you want a `]` in a Regex expression the proper format is to have it immediately after the `[` or immediately after the `[^`. You should amend it to `([^]\]+)`
steven_desu
@steven_desu: Testing in RegexBuddy shows that, with or without the backslash, it performs the same. The reason I included it was to escape the square bracket, as I presumed it was a special character.
Lucanos