Я работаю над функцией автоматической подсказки глоссария для сайта. Это позволит администратору вводить термины глоссария с соответствующими определениями, а затем эти слова будут преобразованы в триггеры всплывающей подсказки в любом месте, где они появляются на интерфейсе.
Вот метод, который я использую:
Все содержимое фильтруется перед выводом с помощью функции, которая ищет с помощью регулярного выражения терминов глоссария и помещает их в теги с классом, который затем выбирается javascript для обработки всплывающей подсказки при наведении курсора.
Что мне нужно сделать, и я не могу понять, так это включить соответствующее определение в качестве атрибута title в диапазон.
Вот мой код на данный момент: (исходные массивы - это просто примеры, в каждом намного больше записей)
function glossary_highlight( $content ) {
$glossary = ['Lorem', 'Ipsum'];
$definitions = ['Lorem is a type of crocodile', 'Ipsum is a kitchen utensil'];
$patterns = [];
foreach ($glossary as $term) {
$patterns[] = '/\b' . $term . '\b/i';
}
$wrapper = '<span class="tooltip" title="XXXX">$0</span>';
$wrapped = preg_replace($patterns, $wrapper, $content);
return $wrapped;
}
Мне нужно заменить XXXX соответствующей записью в массиве $ definitions. Я не могу выполнить регулярное выражение в цикле foreach, потому что тогда он может начать добавлять интервалы в заголовки других интервалов, если определение содержит другой термин из глоссария и т. Д.
Желаемый эффект - учитывая $ content "Lorem ipsum dolor sit amet", возврат из этой функции должен быть:
<span class="tooltip" title="Lorem is a type of crocodile">Lorem</span> <span class="tooltip" title="Ipsum is a kitchen utensil">ipsum</span> dolor sit amet
Первым моим желанием было сделать что-то вроде:
$wrapper = '<span class="tooltip" title="' . $definitions[$key] . '">$0</span>';
Где $ key будет относиться к индексу рассматриваемого термина глоссария, но я не могу понять, как включить это в foreach.
Если я не могу понять все это на PHP, я думаю, я просто применю диапазон всплывающих подсказок и отправлю массив определений в javascript, чтобы добавить оттуда атрибут title, но я бы предпочел не разделять базовую задачу на два языка .. .
Я уверен, что здесь есть совершенно простой ответ, но мой мозг его не увидит! Кто-нибудь может помочь?
РЕДАКТИРОВАТЬ: спасибо lampyridae за его помощь, код ниже работает следующим образом:
function glossary_highlight( $content ) {
$glossary = ['Lorem', 'Ipsum'];
$definitions = ['Lorem is a type of crocodile', 'Ipsum is a kitchen utensil'];
$patterns = [];
foreach ($glossary as $term) {
$patterns[] = '/\b' . $term . '\b/i';
}
$wrappers = [];
foreach ($definitions as $definition) {
$wrappers[] = '<span class="tooltip" title="' . $definition . '">$0</span>';
}
$wrapped = preg_replace($patterns, $wrappers, $content);
return $wrapped;
}
2 ответа
Я вижу два варианта:
- Запустите preg_replace один раз для каждого термина. Если тексты длинные, терминов много, и это делается в реальном времени, это может стать проблемой для производительности.
- Предоставьте множество замен, как вы это делаете для выкроек.
Я думаю, что номер 2 в целом будет быстрее и проще. Идея состоит в следующем:
$wrappers = [];
foreach ($definitions as $definition) {
$wrappers[] = '<span class="tooltip" title="' . $definition . '">$0</span>';
}
… Затем используйте обертки:
$wrapped = preg_replace($patterns, $wrappers, $content);
Я бы хранил ваши токены в едином ассоциативном массиве. Это просто чище и намного легче увидеть совпадения.
$words = [
'lorem' => 'Lorem is a type of crocodile',
'ipsum' => 'Ipsum is a kitchen utensil',
];
Затем строите выкройки. Обратите внимание на использование здесь привязки границы слова \ b, чтобы мы сопоставляли lorem, но не splorems.
$patterns = [];
foreach (array_keys($words) as $word) {
$patterns[] = '/\b' . $word . '\b/i';
}
Затем используйте preg_replace_callback () для создания настраиваемой строки замены на лету:
$newContent = preg_replace_callback($patterns, function ($matches) use ($words) {
return
'<span class="tooltip" title="' .
$words[strtolower($matches[0])] .
'">' . $matches[0] . '</span>';
}, $content);
Похожие вопросы
Новые вопросы
php
PHP — это открытый, мультипарадигмальный, динамически типизированный и интерпретируемый язык сценариев, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.