在Unicode字符的支持下标记Vbulletin帖子中的单词

时间:2015-02-12 11:19:16

标签: php unicode preg-replace vbulletin

我有一个Vbulletin插件,用href替换所有hashtag,但需要自定义,因为它不支持非英文字符。

例如:#vbulletin将变为 #vbulletin ,但#može将变为 #mo ,仅将#mo转换为哈希标记。

由于我不太擅长PHP,我会复制文件的内容,以便更好地理解。

<?php
$hashes = array();
do
{
    if (!$matches = USERTAG::match(preg_replace('#\[(\w+?)(?>[^\]]*?)\](.*)(\[/\1\])#siU', '', $message), 'hash'))
    {
        break;
    }

foreach ($matches as $hash)
{
    $hash = trim($hash);

    if (!$hash)
    {
        continue;
    }

    $hashes[] = htmlspecialchars_uni($hash);
}

if (!empty($hashes))
{
    $hashes = array_unique($hashes);

    if ($info['postid'])
    {
        $hashlist = USERTAG::$db->fetchAll('
            SELECT *
            FROM $usertag_hash AS hash
            WHERE hash :queryList
                AND postid = ?
                AND type = ?
        ', array(
            ':queryList' => USERTAG::$db->queryList($hashes),
            $info['postid'],
            $info['type']
        ));
        foreach ($hashlist as $results_r)
        {
            $key = array_search($results_r['hash'], $hashes);
            if ($key === false)
            {
                continue;
            }

            unset($hashes[$key]);
        }
    }

    foreach ($hashes as $key => $hash)
    {
        $hash = unhtmlspecialchars($hash);

        if (!$hash)
        {
            unset($hashes[$key]);
            continue;
        }           

        $possible = array('/\[hash]' . preg_quote($hash, '/') . '\[\/hash\]/iU', '/#' . preg_quote($hash) . '/iU');
        $message = preg_replace($possible, '[URL=' . $this->registry->options['bburl'] . '/usertag.php?do=list&action=hash&hash=' . urlencode($hash) . ']#' . $hash . '[/URL] ', $message, -1, $found);
    }

    $info['hash'] = $hashes;                        
    }
}
while (false);
?>

在我看来,这是需要改变的界限:

        if (!$matches = USERTAG::match(preg_replace('#\[(\w+?)(?>[^\]]*?)\](.*)(\[/\1\])#siU', '', $message), 'hash'))

正如我所说,我在PHP方面表现不佳,所以也许我错了。我尝试使用我在这里或其他网站上找到的示例来更改某些部分,但没有任何成功。

我真的很感激任何帮助,所以我可以用塞尔维亚拉丁字符标记单词,如šđžčćŠĐŽČĆ,如果可能的话,还可以标记整个塞尔维亚西里尔字符。

我的论坛上的编码是UTF-8,数据库整理是utf8_general_ci,塞尔维亚字母在帖子中正确显示。我不知道是不是重要,但以防万一。

提前致谢。

问候。

1 个答案:

答案 0 :(得分:0)

问题可能来自定义处理用户标签的两种模式的这一行:

$possible = array('/\[hash]' . preg_quote($hash, '/') . '\[\/hash\]/iU', '/#' . preg_quote($hash) . '/iU');

你可以删除愚蠢的修饰符U (大部分时间完全没用)使贪婪量词非贪婪,反之亦然,并添加u修饰符,使其能够处理unicode字符。所以, 它可以像这样重写:

$possible = array('~\[hash]' . preg_quote($hash, '~') . '\[/hash]~iu', '/#' . preg_quote($hash) . '/iu');

模式:#\[(\w+?)(?>[^\]]*?)\](.*)(\[/\1\])#siU也可以像这样重写:

#\[(\w+)[^]]*](.*?)(\[/\1])#siu

不确定这会解决所有问题,但它至少是一个开始。