2010-10-19 4 views
0

Я использую preg_match_all получить процитированные пользователей от поста на форуме, как так:PHP/Regex/preg_match_all

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

в $ после строки, как правило, быть что-то вроде:

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

preg_match_all функция отлично работает, когда только один пользователь котируется, и возвращает что-то вроде:

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

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

) 

Мой код проходит через каждый $ quotedUsers [1], чтобы получить имена пользователей, и я подумал, что все в порядке. Кроме этого, когда два пользователя цитируются, это выглядит примерно так:

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 
     ) 

) 

Что происходит и как это исправить? Я думал, что preg_match_all просто поместил бы все имена пользователей в массив $ quotedUsers [1].

+0

Вот почему вы должны [использовать BBCode парсер] (http://stackoverflow.com/questions/488963/best-way- to-parse-bbcode «Лучший способ разбора BBCode»), как это было предложено в [вашем предыдущем вопросе] (http://stackoverflow.com/questions/3967228/php-and-regex-problem «Проблема PHP и Regex»). [Регулярное выражение не может разбираться с BBCode] (http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html «Блог Kore Nordmanns: не анализируйте HTML с помощью регулярных выражений») – Gordon

ответ

0

На своем регулярном выражении вы должны сделать * не жадный

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

Просто надо добавить? * после

0

Сделать * нежадные:

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

Это соответствует любому символу, до тех пор, следующего) найден. В противном случае он будет соответствовать как можно большему количеству символов (это будет соответствовать последним )).

Более подробно об этом в Repetition with Star and Plus

0

Проблема в том, что ваш текущий RegExp, с .* это жадные и захватывая слишком много информации.

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

Должно быть.

Измененный: Будем надеяться, что имена пользователей не имеют квадратную скобку ...

+0

Не будет ли это останавливаться в пробелах? Имена пользователей могут иметь пробелы и символы. – katoth

+0

Это деталь, которая была бы удобна в исходном вопросе ... Во всяком случае, мой код был изменен. Я могу сказать, что ответы Viper & Felix также функциональны. –

+0

Если вы хотите '' 'в выражении Regex, правильный формат должен иметь его сразу после' ['или сразу после' [^ '. Вы должны изменить его на '([^] \] +)' – stevendesu