正则表达式不区分大小写,有/没有空格

时间:2015-12-07 16:03:36

标签: php regex highlight highlighting

在正则表达式模式中不是那种知识,并且在阅读了所有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);

    }
}

有些单词没有突出显示(标有红色箭头的单词):

Words missing out

我不知道它是否有帮助,但这里是用于搜索文本的“术语”数组:

Words being searched

编辑。搜索的字符串只是纯文字:

  

Abaxial Xxxxx acaule Acaule xxxxxx xxx; xxxxx xxx背轴esporos。   背面

编辑。添加了PHP代码小提琴

http://phpfiddle.org/main/code/079ad24318f554d9f2ba

有任何帮助吗?我真的不太了解正则表达式......

2 个答案:

答案 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\.\,\!\?\<])
  1. 有3对标记组由3对( ... )定义。

  2. 第一个标记组与任何空格字符匹配。如果在字符串的开头没有像Abaxial那样的空格字符,则忽略该字。

    \s置于字符类中,即在[ ... ]内,实际上并不需要\s本身就是一个字符类。 ([\s])(\s)相等。

  3. 第二个标记组仅匹配数组中的单词。

  4. 第三个标记组匹配

    • 任何空格字符,
    • 或句号,
    • 或逗号,
    • 或感叹号,
    • 或问号,即标准标点符号,
    • 或左尖括号(来自HTML或XML标记)。

    左侧分号或冒号不匹配,其他非单词字符也会因正匹配而被忽略。

    如果字符串末尾没有abaxial之类的字符,则搜索结果为否定。

    顺便说一下:([\s.,!?<])等于([\s\.\,\!\?\<]),只有\](总是)和-(取决于位置)必须转义为字符类定义中的反斜杠,以解释为文字字符。好吧,[也应该在[ ... ]内使用反斜杠进行转义,以便于阅读。

  5. 因此很清楚为什么字符串开头的Abaxial和字符串末尾的abaxial不匹配。

    但为什么Acaule不匹配?

    嗯,这个单词留给acaule,左边有一个空格,右边有一个空格,正面匹配。所以acaule的空间权利已经被用于这场积极的比赛。因此,对于Acaule,此单词不再留有空白字符。

    \b这意味着字边界不匹配任何可能与\W*?而不是([\s])一起使用的字符,而不是([\s\.\,\!\?\<]),以避免匹配字符串中的子字符串字。

    可能会像

    $key = '(\W*?)(\b' . $key . '\b)(\W*?)';
    

    \W*?表示任何字符字符为非贪婪的0次或更多次。

    \W?表示任意字符0或1次,如果替换效果更好,也可用于第一个和第三个捕获组。

    但是什么是正确的搜索字符串取决于你想要的替换结果。

    我根本没有安装PHP解释器,因此无法尝试使用PHP代码替换的内容,因此在替换完所提供的示例字符串后,您希望看到的内容。