2014-03-03 46 views
3

我使用此代码使用户标记和主题标签可以在我的小网站上工作。Preg替换HTML撇号

$string = $text; 

$pattern = '/(^|\W)(@([a-zA-Z0-9_\-]+))/'; 
$replacement = '$1<a class="blue" href="/app/profile/$3">$2</a>'; 
$text = preg_replace($pattern, $replacement, $string); 
$string = $text; 

$pattern = '/(^|\W)(#([a-zA-Z0-9_\-]+))/'; 
$replacement = '$1<a class="blue" href="/app/find/search/$3">$2</a>'; 
$text = preg_replace($pattern, $replacement, $string); 
echo $text; 

我的数据库保存这样的文本的所有作品:

he&#039;s 

(他)

然而,当它输出通过这个代码的话不归,输出如下:

he&amp;<a class="blue" href="/app/find/search/039">#039</a>;s 

当shold只是 “他” 怎能时I g等preg取代它看作是一个撇号?

+0

你没有让'&'和','在'$ pattern',所以他们被剥离出来。 –

+0

在我的回答中有没有你不明白的地方?我没有看到任何评论。 –

回答

0

改变你的第二个模式。

$pattern = '/(^|[^\w\&])(#([a-zA-Z0-9_\-]+))/'; 

它是什么,它不会匹配,如果井号标签立即&之前。所以&#039;不会被匹配。 &#sometag也不会被匹配,但我相信这很好,因为如果前面有一些文本,你已经不符合标签。

0

您可以使用一个向后看断言:

/(?<=^|\s)(#|@)(\w+)/ 

一个字符串的起点或一个空间(包括制表符,换行符等)开头,哈希或符号,然后在至少一个“字样”字样。

所以:

$string = preg_replace_callback('/(?<=^|\s)(#|@)(\w+)/', function($match) { 
    switch ($match[1]) { 
     case '#': 
      $format = '<a class="blue href="/app/find/search/%s">%s</a>'; 
      break; 

     case '@': 
      $format = '<a class="blue href="/app/profile/%s">%s</a>'; 
      break; 

     default: 
      return $match[0]; 
    } 

    return sprintf($format, urlencode($match[2]), $match[1] . $match[2]); 
}, $string);