0

让我很困惑!这是代码。我得到 1 for $mc 那是一个计数器!并且在我设置 3 次后不能从 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
4

2 回答 2

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子句传入,以跟踪已处理的匹配数。在三个替换之后,它将简单地返回匹配的字符串。

于 2013-09-03T08:45:03.217 回答
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;
于 2013-09-03T08:48:48.370 回答