我需要在UTF-8 $文本中突出显示与$ key匹配的单个单词或短语(整个单词,而不是子字符串)。这种匹配必须不区分大小写和变音符号。突出显示的文本必须保持原样(包括大写/小写字符和变音符号,如果存在)。
以下表达式达到了目标的一半:
$text = preg_replace( "/\b($key)\b/i", '<div class="highlight">$1</div>', $text );
不区分大小写,并且匹配整个单词,但是如果匹配$ key的$ text部分包含$ key中不存在的变音标记,则不会突出显示这些文本。 例如。我想在$ text中通过$ key =“ bjorn kallstrom”突出显示“BjörnKällström”。
欢迎任何绝妙的主意(使用preg_replace或其他PHP函数)。
答案 0 :(得分:1)
一个想法是将键转换为用字符类替换所有有问题字符的模式:
$corr = ['a' => '[aàáâãäå]', 'o' => '[oòóôõö]',/* etc. */];
$key = 'bjorn kallstrom';
$pattern = '/\b' . strtr($key, $corr) . '\b/iu';
$text = preg_replace($pattern, '<em class="highlight">$0</em>', $text);
请注意,由于您要处理Unicode字符,因此需要使用u修饰符来避免意外行为,尤其是在单词边界方面。
如果您的按键已经包含重音符号,请先将其转换为ascii:
$key = 'björn kallstrom';
$key = iconv('UTF-8', 'ASCII//TRANSLIT', $key);
(如果您获得?
代替字母,则意味着您的语言环境设置为C或POSIX。在这种情况下,请将其更改为en_US.UTF-8,或者将其更改为系统。请参见setlocale)
还要看看非常有用的intl类:Normalizer和Transliterator。
注意:如果要突出显示多个键,请一次完成所有操作。按长度对数组进行排序(使用mb_strlen
的数组中最长的数组),使用array_map
音译ascii键,并用|
插入数组。目标是获得模式:'/\b(?:' . implode('|', $keys) . ')\b/iu'
与bj[oòóôõö]rn k[aàáâãäå]llstr[oòóôõö]m
单独出现在bj[oòóôõö]rn
之前(例如)。
答案 1 :(得分:0)
仅通过函数调用是不可能的,您将必须实现它。
$document->documentElement->textContent
)中提取文本$words[$normalized][] = $original
)-基本上,这为您提供了每个规范化单词的变体列表。((word1_v1|word1_v2)\s*(word2_v1|word2_v2))u
并验证(^(word1_v1|word1_v2)\s*(word2_v1|word2_v2)$)u
$xpath->evaluate('//text()')
中的文本节点preg_split()
通过搜索字符串分隔文本,捕获定界符(搜索匹配项)