在正则表达式模式中不是那种知识,并且在阅读了所有wiki和参考文献后,我发现我在更改单词检测和高亮显示的模式时遇到了问题。
我在另一个stackoverflow回答中找到了一个函数,它完成了所需的一切但现在我发现它错过了一些东西
功能是:
function ParserGlossario($texto, $termos) {
$padrao = '\1<a href="#" class="termo">\2</a>\3';
if (empty($termos)) {
return $texto;
}
if (is_array($termos)) {
$substituir = array();
$com = array();
foreach ($termos as $key => $value) {
$key = $value;
$value = $padrao;
// $key = '([\s])(' . $key . ')([\s\.\,\!\?\<])';
$key = '([\s])(' . $key . ')([\s\.\,\!\?\<])';
$substituir[] = '|' . $key . '|ix';
$com[] = empty($value) ? $padrao : $value;
}
return preg_replace($substituir, $com, $texto);
} else {
$termos = '([\s])(' . $termos . ')([\s])';
return preg_replace('|'.$termos.'|i', $padrao, $texto);
}
}
有些单词没有突出显示(标有红色箭头的单词):
我不知道它是否有帮助,但这里是用于搜索文本的“术语”数组:
编辑。搜索的字符串只是纯文字:
Abaxial Xxxxx acaule Acaule xxxxxx xxx; xxxxx xxx背轴esporos。 背面
编辑。添加了PHP代码小提琴
http://phpfiddle.org/main/code/079ad24318f554d9f2ba
有任何帮助吗?我真的不太了解正则表达式......
答案 0 :(得分:1)
尝试
$key = '(^|\b)(' . $key . ')\b';
的插入内容
$key = '([\s])(' . $key . ')([\s\.\,\!\?\<])';
应该有所帮助。你的比赛仍然会在第二组,但没有第三组,我认为第一组不应该被触及,所以我相信这个
$padrao = '\1<a href="#" class="termo">\2</a>\3';
最好是
$padrao = '<a href="#" class="termo">$2</a>';
忘了(对不起): 改变
$substituir[] = '|' . $key . '|ix';
到
$substituir[] = '#' . $key . '#ix';
我还会使用字符串
$com = empty($value) ? $padrao : $value;
而不是数组,在这种情况下不需要。
答案 1 :(得分:1)
让我们一起查看$key
的值,例如数组元素acaule
。
([\s])(acaule)([\s\.\,\!\?\<])
有3对标记组由3对(
... )
定义。
第一个标记组与任何空格字符匹配。如果在字符串的开头没有像Abaxial
那样的空格字符,则忽略该字。
将\s
置于字符类中,即在[
... ]
内,实际上并不需要\s
本身就是一个字符类。 ([\s])
和(\s)
相等。
第二个标记组仅匹配数组中的单词。
第三个标记组匹配
左侧分号或冒号不匹配,其他非单词字符也会因正匹配而被忽略。
如果字符串末尾没有abaxial
之类的字符,则搜索结果为否定。
顺便说一下:([\s.,!?<])
等于([\s\.\,\!\?\<])
,只有\
和]
(总是)和-
(取决于位置)必须转义为字符类定义中的反斜杠,以解释为文字字符。好吧,[
也应该在[
... ]
内使用反斜杠进行转义,以便于阅读。
因此很清楚为什么字符串开头的Abaxial
和字符串末尾的abaxial
不匹配。
但为什么Acaule
不匹配?
嗯,这个单词留给acaule
,左边有一个空格,右边有一个空格,正面匹配。所以acaule
的空间权利已经被用于这场积极的比赛。因此,对于Acaule
,此单词不再留有空白字符。
有\b
这意味着字边界不匹配任何可能与\W*?
而不是([\s])
一起使用的字符,而不是([\s\.\,\!\?\<])
,以避免匹配字符串中的子字符串字。
可能会像
$key = '(\W*?)(\b' . $key . '\b)(\W*?)';
\W*?
表示任何非字符字符为非贪婪的0次或更多次。
\W?
表示任意非字符0或1次,如果替换效果更好,也可用于第一个和第三个捕获组。
但是什么是正确的搜索字符串取决于你想要的替换结果。
我根本没有安装PHP解释器,因此无法尝试使用PHP代码替换的内容,因此在替换完所提供的示例字符串后,您希望看到的内容。