Я хочу отметить все слова внутри текста, кроме тех, которые находятся внутри тега.
Основано на идее от Вот, Мне удалось сделать следующее:
preg_replace("/(\b(\p{L}+)\b)(?!([^<]+)?>)/", "<mark>$1</mark>", $input);
Что отлично работает, за исключением некоторых странных поведений при использовании с акцентом. Примеры:
lorem ipsúm dolor <a href="#" title="sit">sit</a> amet consectetur
[OK] => <mark>lorem</mark> <mark>ipsúm</mark> <mark>dolor</mark> <a href="#" title="sit"><mark>sit</mark></a> <mark>amet</mark> <mark>consectetur</mark>
ação ipísum
[NOT OK] => <mark>a</mark>çã<mark>o</mark> <mark>ip</mark>í<mark>sum</mark>
Есть идеи, почему это происходит и как это исправить?
Спасибо
Пара вещей здесь:
u
,\p{M}
,Таким образом, регулярное выражение растет:
$input = 'lorem <a href="#">foo</a> ação';
echo preg_replace(
'/\b((?:\p{L}\p{M}*)+)\b(?!([^<]+)?>)/u',
"<mark>$1</mark>",
$input
);
Выходы:
<mark>lorem</mark> <a href="#"><mark>foo</mark></a> <mark>ação</mark>
Пока все хорошо, правда? Давайте добавим это «ё» и посмотрим.
$input = 'lorem <a href="#">foo</a> ação evè';
Сетевые выходные данные:
<mark>lorem</mark> <a href="#"><mark>foo</mark></a> <mark>ação</mark> <mark>eve</mark>̀
Это не правильно. Оказывается сокращение слова границы \b
все еще действует немного глупо, даже в режиме UTF-8. Таким образом, вы должны заменить его некоторыми негативными взглядами.
Пока мы на этом, давайте также использовать \pL
на месте \p{L}
поскольку фигурные скобки являются необязательными для однобуквенных категорий Unicode.
$input = 'lorem <a href="#">foo</a> ação evè';
echo preg_replace(
'/(?<![\pL\pM])((?:\pL\pM*)+)(?![\pL\pM])(?!([^<]+)?>)/u',
"<mark>$1</mark>",
$input
);
Выходы:
<mark>lorem</mark> <a href="#"><mark>foo</mark></a> <mark>ação</mark> <mark>evè</mark>
Демо в https://eval.in/194139.
Использовать u
модификатор:
$arr = Array('orem ipsúm dolor <a href="#" title="sit">sit</a> amet consectetur','ação ipísum');
foreach($arr as $input) {
echo preg_replace("/(\b(\p{L}+)\b)(?!([^<]+)?>)/u", "<mark>$1</mark>", $input),"\n";
// here __^
}
Выход:
<mark>orem</mark> <mark>ipsúm</mark> <mark>dolor</mark> <a href="#" title="sit"><mark>sit</mark></a> <mark>amet</mark> <mark>consectetur</mark>
<mark>ação</mark> <mark>ipísum</mark>