0

假设我们正在编写一个自定义模板系统,我们希望在模板包含的地方显示一个链接{{link:http://example.com/something}}click here{{link}}

解析这个的最佳方法是什么?

我能想到的一些方法: 使用substr. preg_replace与反向替换等一起使用。

4

1 回答 1

3

对于我自己的解析器,我混合使用“strpos / substr”和 preg_replace。为什么?好吧,这一切都在数字中。

如果要解析的字符串几乎只包含一个 {{link}} 标记,没有 Start- 和 Endnoice,preg_replace 会更快,例如

STARTNOICE{{link:http://example.com/something}}click here{{link}}ENDNOICE

但是,与 substr / strpos 相比,Endnoice 中的字符越多,preg_replace 就越慢 :) Endnoice 中只有 100 个字符,将使 substr / strpos 比 preg_match 更快!

证明这一点的最好方法是使用原因代码。所以这是一个测试脚本。它将 substr 的时间总和与 preg_match 进行比较

尽管 substr 需要更多代码,但它更有效:)

格雷茨,JB

ps一些结果:

Startnoice = Endnoice = 100, /w 100 loops
$substrTime:
0.004448 Seconds
$pregTime:
0.004752 Seconds

.

Startnoice = Endnoice = 1000, /w 100 loops
$substrTime:
0.005598 Seconds
$pregTime:
0.023844 Seconds  << waaaay slower

.

Startnoice = Endnoice = 10000, /w 100 loops
$substrTime:
0.009028 Seconds
$pregTime:
0.278836 Seconds  << Dont use preg_replace

.

<?PHP
$startNoice = 1;
$endNoice   = 100;

for( $jb = 0; $jb < 100; $jb++ )
{
    $string = randomgenerator( $startNoice ) . '{{link:http://example.com/something}}click here{{link}}.' . randomgenerator( $endNoice );

/**************/
// Strpos / substr
/**************/

/* Start the timer */
    $Start = '{{link:';
    $StartEnd = '}}';
    $Stop = '{{link}}';

    $StartLen = strlen( $Start );
    $StartEndLen = strlen( $StartEnd );
    $StopLen = strlen( $Stop );

    $time_start = microtime_float();
    $strpos['Start']    = strpos( $string, $Start );

    $start = substr( $string, 0, $strpos['Start']);
    $end = substr( $string, $strpos['Start'] );

    $strpos['StartEnd'] = strpos( $end, $StartEnd, $StartLen );
    $strpos['Stop']     = strpos( $end, $Stop, $StartLen );

    $url  = substr( $end, $strpos['Start'] + $StartLen, ($strpos['StartEnd'] - $strpos['Start'] - $StartLen)  );
    $text = substr( $end, $strpos['StartEnd'] + $StartEndLen, ($strpos['Stop'] - $strpos['StartEnd'] - $StartEndLen) );

// Replace the link
    $NewString1 = $start . '<a href="' . $url . '">' . $text . '</a>' . substr( $end, $strpos['Stop'] + $StopLen );
/* Stop the tumer */
    $time_end = microtime_float();
    $substrTime[] = $time_end - $time_start;


/**************/
// Preg_match
/**************/
    $time_start = microtime_float();
    $NewString2 = preg_replace('/{{link:(.*)}}(.*){{link}}/', '<a href="$1">$2</a>', $string);
    $time_end = microtime_float();
    $pregTime[] = $time_end - $time_start;
}

echo '$substrTime: . <br />';
echo round( array_sum( $substrTime ), 6) . ' Seconds';
echo '<br />';
echo '$pregTime: . <br />';
echo round( array_sum( $pregTime ), 6) . ' Seconds';

function randomgenerator( $length )
{
    $string = 'abcdefghijklmnopqrstuvwxyz01234567890!@#$%^&*()_+=-{}][|\::",./';
    $r = '';
    for( $i = 0; $i < $length; $i ++ )
    {
        $r .= $string[ rand(0, strlen( $string ) -1 ) ];
    }
    return $r;
}

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
?>
于 2012-12-03T14:16:53.143 回答