【问题标题】:Preg_Replace and UTF8Preg_Replace 和 UTF8
【发布时间】:2011-01-05 00:18:07
【问题描述】:

我正在增强我们的 video search page 以突出显示结果中的搜索词。因为用户可以输入judas priest,并且视频的文本中有Judas Priest,所以我必须使用正则表达式来保留原始文本的大小写。

我的代码有效,但我遇到了š, č and ž 等特殊字符的问题,似乎Preg_Replace() 只有在大小写相同的情况下才会匹配(尽管有/ui 修饰符)。 我的代码:

$Content = Preg_Replace ( '/\b(' . $term . '?)\b/iu', '<span class="HighlightTerm">$1</span>', $Content );

我也试过这个:

$Content = Mb_Eregi_Replace ( '\b(' . $term . '?)\b', '<span class="HighlightTerm">\\1</span>', $Content );

但它也不起作用。如果搜索词是“SREČA”,它将匹配“SREČA”,但如果搜索词是“sreča”,它将不匹配(反之亦然)。

那么我该如何做呢?

更新:我设置了区域设置和内部编码:

Mb_Internal_Encoding ( 'UTF-8' );
$loc = "UTF-8";
putenv("LANG=$loc");
$loc = setlocale(LC_ALL, $loc);

【问题讨论】:

  • 您是否考虑过如果用户在搜索查询中输入特殊字符(例如/*)会发生什么?
  • 搜索词在我对它做任何事情之前都会被清理。不过感谢您的评论。
  • 您可以使用preg_quote代替“消毒”

标签: php regex utf-8


【解决方案1】:

我现在觉得自己很愚蠢,但问题根本不在于 Preg_* 函数。我不知道为什么,但我首先检查了给定的术语是否甚至在带有StriPos 的字符串中,并且由于该函数不是多字节安全的,如果文本的大小写与搜索词,所以 Preg_Replace 甚至没有被调用。

所以这里要吸取的教训是,如果您有 UTF8 字符串,请始终使用多字节版本的函数。

【讨论】:

  • 阿门,兄弟。阿门。
【解决方案2】:

不知道你的问题出在哪里,但我只是把这个小测试用例放在一起:

<?php

$uc = "SREČA";

mb_internal_encoding('utf-8');
echo $uc."\n";
$lc = mb_strtolower($uc);
echo $lc."\n";

echo preg_replace("/\b(".preg_quote($uc).")\b/ui", "<span class='test'>$1</span>", "test:".$lc." end test");

这是我机器上的输出:

SREČA
sreča
test:<span class='test'>sreča</span> end test

似乎工作正常?

【讨论】:

  • 添加mb_regex_encoding 并不能解决问题(我已经有了另外两个):\
【解决方案3】:

如果我没记错的话,preg_match 使用当前语言环境。尝试setting the locale 这些字符所属的语言。您可能也需要基于 utf8 的语言环境。如果您的页面中有多种语言,您也许可以找到一个通用的国际语言环境。

另见:http://www.phpwact.org/php/i18n/utf-8

【讨论】:

  • UTF-8 可能不是任何系统上的有效语言环境。尝试在 shell 上运行 locale -a 以获取支持的语言环境。你可能想要一个看起来像en_GB.utf8
猜你喜欢
  • 2015-09-22
  • 1970-01-01
  • 2015-10-02
  • 2016-02-07
  • 2013-07-17
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多