繁体   English   中英

PHP:查找子字符串,使用动态属性包装标记

[英]PHP: Find substrings, wrap in tags with dynamic attributes

我正在为网站制作词汇表自动工具提示功能。 这将允许管理员输入带有相应定义的术语表术语,然后这些单词将在它们出现在前端的任何地方被制作成可移动的工具提示触发器。

这是我正在使用的方法:

所有内容在通过函数输出之前进行过滤,该函数使用正则表达式搜索词汇表术语并将其包装在带有类的标记中,然后由javascript拾取以处理工具提示的悬停显示。

我需要做的,也无法弄清楚的是,还要在span上包含适当的定义作为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;
}

我需要用$ definitions数组中的相应条目替换XXXX。 我无法在foreach循环中执行正则表达式,因为如果定义包含另一个词汇表术语,它可能会开始在其他跨度的标题内添加跨度。

期望的效果 - 给出“Lorem ipsum dolor sit amet”的$ content,这个函数的返回应该是:

<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属性,但我宁愿不将两个语言的基本任务分开。 。

我相信这里有一个非常简单的答案,但我的大脑不会看到它! 有人可以帮忙吗?

编辑:感谢萤火虫对他的帮助,下面的代码如下:

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;
}

我看到两个选择:

  1. 为每个术语运行一次preg_replace。 如果文本很长,那么术语很多并且这是实时完成的,这可能会成为性能问题。
  2. 提供一系列替换,就像您对模式一样。

我认为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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM