如何用PHP实现植物拉丁名指定部分的<em>标签包裹,避免标签拆分
植物拉丁名批量添加标签的优化方案
需求说明
需要将数据库中存储的纯文本植物拉丁名,为特定部分添加<em>标签,规则如下:
- 连续符合条件的单词需合并为一个
<em>标签包裹,避免单个单词拆分导致的</em> <em>问题 - 排除
subsp.、var.、f.、(voir)、hybride这些特定词汇,不添加标签 - 单引号包裹的内容(如
'Angelica')也不添加标签
示例:
输入:Androsace angrenica 'Angelica' subsp. Violaceae
期望输出:<em>Androsace angrenica</em> 'Angelica' subsp. <em>Violaceae</em>
优化后的PHP实现
// 无需添加标签的词汇列表 $excludeWords = ["subsp.", "var.", "f.", "(voir)", "hybride"]; // 测试用植物拉丁名 $name = "Androsace angrenica 'Angelica' subsp. Violaceae"; $words = explode(" ", $name); $newContent = []; $inEm = false; // 标记当前是否处于<em>标签内 foreach ($words as $word) { // 判断当前单词是否需要排除 $isExcluded = in_array($word, $excludeWords) || preg_match("/'[^']+'/", $word); if (!$isExcluded) { if (!$inEm) { // 未处于标签内,打开<em> $newContent[] = "<em>"; $inEm = true; } $newContent[] = $word; } else { if ($inEm) { // 当前处于标签内,先关闭<em> $newContent[] = "</em>"; $inEm = false; } $newContent[] = $word; } } // 循环结束后,若仍处于标签内,关闭标签 if ($inEm) { $newContent[] = "</em>"; } // 拼接最终结果 echo implode(" ", $newContent);
代码逻辑说明
- 状态标记:用
$inEm变量跟踪当前是否在<em>标签范围内,解决连续单词的合并问题 - 排除判断:同时检查词汇是否在排除列表,或是否是单引号包裹的内容
- 标签切换:
- 遇到需要添加标签的单词时,若未打开标签则先打开,直接追加单词
- 遇到排除项时,若当前在标签内则先关闭,再追加排除项
- 收尾处理:循环结束后检查是否还处于标签内,避免遗漏关闭标签
多格式测试验证
针对不同格式的拉丁名,均可正确生成结果:
- 输入:
Allium obliquum
输出:<em>Allium obliquum</em> - 输入:
Allium ostrowkianum (voir) A. oreophilum
输出:<em>Allium ostrowkianum</em> (voir) <em>A. oreophilum</em> - 输入:
Allium senescens subsp. glaucum
输出:<em>Allium senescens</em> subsp. <em>glaucum</em> - 输入:
Allium sikkimense
输出:<em>Allium sikkimense</em> - 输入:
Androsace × pedemontana
输出:<em>Androsace × pedemontana</em>
内容的提问来源于stack exchange,提问作者Marc DG
相关产品推荐
相关产品推荐

