регулярное выражение без учета регистра и с / без пробелов

Не будучи осведомленным в шаблонах регулярных выражений и после прочтения всех вики и ссылок, я обнаружил, что у меня возникают проблемы с изменением шаблона для обнаружения слов и выделения текста.

Я нашел функцию в другом ответе 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

Любая помощь? Я действительно не знаю много о регулярных выражениях …

2

Решение

пытаться

$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

Другие решения

Давайте посмотрим вместе на ценность $key например для элемента массива acaule,

([\s])(acaule)([\s\.\,\!\?\<])
  1. Есть 3 группы маркировки, определяемые 3 парами (),

  2. Первая группа маркировки соответствует любому символу пробела. Если нет пробела, как для Abaxial в начале строки слово игнорируется.

    Ввод \s в класс персонажа, то есть в пределах [] не очень нужно здесь, как \s сам по себе класс персонажа. ([\s]) а также (\s) равны.

  3. Вторая группа разметки соответствует только слову из массива.

  4. Матчи третьей маркировки совпадают

    • либо любой символ пробела,
    • или период,
    • или запятая,
    • или восклицательный знак,
    • или вопросительный знак, то есть стандартные знаки препинания,
    • или левая угловая скобка (из тега HTML или XML).

    Точка с запятой или двоеточие не совпадают, и другие несловарные символы также игнорируются для положительного соответствия.

    Если нет таких символов, как для 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-код делает с заменой, и, следовательно, что вы хотели бы увидеть после замены, выполненной в предоставленной строке примера.

1

По вопросам рекламы [email protected]