2013-09-03 3 views
0

путать меня много! вот код. Я получаю 1 за $ mc, что является счетчиком! и не может выйти из цикла foreach через 3 раза.php - счетчик не работает в пределах foreach

Код: Текст

$mc=0;  
if(preg_match_all('/(\@\`)([^`]*)(`\:)/i', $txt, $matches)) {  
    foreach(@$matches[2] as $m) { 
     $mc++; 
     if($mc>3) 
      break; 

    $txt = str_replace("@`".$m."`:",'<a href="profile-'.$m.'">'.$m.'</a>:',$txt);  
    } 
} 

образец:

@`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 
+2

Что '$ txt'? :) –

+0

У вас есть достаточно совпадений? – putvande

+5

Предупреждения о заглушении настолько ошибочны ... – Leri

ответ

2

Это происходит потому, что вы делаете замену отдельно от процесса согласования, поэтому несколько одинаковых записей заменяются. Рассмотрите возможность использования preg_replace_callback() вместо:

$txt = '@`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234 @`test`: test1234'; 

$mc = 0; 
echo preg_replace_callback('/@`([^`]+)`(?=:)/', function($match) use (&$mc) { 
    if (++$mc <= 3) { 
     return sprintf('<a href="profile-%s">%s</a>', 
      urlencode($match[1]), 
      htmlspecialchars($match[1], ENT_QUOTES, 'UTF-8') 
     ); 
    } else { 
     return $match[1]; 
    } 
}, $txt); 

Выход:

<a href="profile-test">test</a>: test1234 
<a href="profile-test">test</a>: test1234 
<a href="profile-test">test</a>: test1234 
test: test1234 test: test1234 test: test1234 test: test1234 test: test1234 test: test1234 test: test1234 test: test1234 

Анонимная функция, которая используется в качестве второго параметра делает фактическую замену; он получает совпадение и должен возвращать заменяющую строку; параметр $mc передается через предложение use, чтобы отслеживать, сколько совпадений было обработано. После трех замен он просто вернет совпадающую строку.

+0

Почему str_replace влияет на эту переменную? Я проверю ваш код, спасибо – exim

+0

Потому что 'str_replace ('@' test'', 'xxx') 'будет выполнять множество замен в исходной строке. –

+0

Я только что получил. да, вы правы, все теги (@test) одинаковы и заменяются! поэтому код правильный. – exim

1

Вы переписываете $txt всегда. Вы должны объединить строку с .=

$string .= str_replace("@`".$m."`:",'<a href="profile-'.$m.'">'.$m.'</a>:',$txt); 

Так как это целое:

$mc=0;  
if(preg_match_all('/(\@\`)([^`]*)(`\:)/i', $txt, $matches)) {  
    foreach($matches[2] as $m) { 
     $mc++; 
     if($mc>3) 
      break; 

     $string .= str_replace("@`".$m."`:",'<a href="profile-'.$m.'">'.$m.'</a>:',$txt);  
    } 
} 

echo $string; 
Смежные вопросы