Не будучи осведомленным в шаблонах регулярных выражений и после прочтения всех вики и ссылок, я обнаружил, что у меня возникают проблемы с изменением шаблона для обнаружения слов и выделения текста.
Я нашел функцию в другом ответе 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);
}
}
Некоторые слова не выделяются (те, которые отмечены красными стрелками):
И я не знаю, помогает ли это, но вот массив «терминов», который используется для поиска текста:
РЕДАКТИРОВАТЬ. Разыскиваемая строка — это просто текст:
Абаксиал Xxxxx acaule Acaule xxxxxx xxx; ххххх ххх абаксиал эспорос.
абаксиальный
РЕДАКТИРОВАТЬ. Добавлена скрипта PHP кода
http://phpfiddle.org/main/code/079ad24318f554d9f2ba
Любая помощь? Я действительно не знаю много о регулярных выражениях …
пытаться
$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;
вместо массива он не нужен в этом случае.
Давайте посмотрим вместе на ценность $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-код делает с заменой, и, следовательно, что вы хотели бы увидеть после замены, выполненной в предоставленной строке примера.