You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:不使用preg_split实现等效功能的PHP代码,需含位置索引

实现自定义的带位置键的字符串拆分功能

我来帮你搞定这个需求!你想要实现类似preg_split的效果,但同时要把每个文本段的起始位置作为数组的键,而且不能直接用preg_split——这个思路很清晰,我们可以通过preg_match_all结合字符串截取来实现。

问题分析

你之前的代码只匹配了<span>开始标签,既没处理结束标签,也没提取标签前后/内部的文本,而且$strpos变量没有赋值,自然无法得到正确的位置键。我们需要先定位所有的<span>开始和结束标签的位置,再以此为分割点提取对应的文本段,同时记录每个文本段的起始位置。

解决方案代码

<?php
$string = '<p>i am a sentence <span id="blah"> im content inside of the span </span> im another sentence <span id="anId">i m another span content</span> im the last sentence in this p tag <span id="last">im the third span tag in this p tag</span></p>';

// 匹配所有<span>开始标签和</span>结束标签,同时捕获它们的起始位置
preg_match_all('/(<span[^>]*>|</span>)/', $string, $matches, PREG_OFFSET_CAPTURE);

$result = [];
$currentPos = 0;
$inSpan = false; // 标记当前是否处于<span>标签内部

foreach ($matches[0] as $match) {
    $tag = $match[0];
    $tagStartPos = $match[1];
    $tagLength = strlen($tag);

    if (!$inSpan) {
        // 提取<span>标签之前的外部文本
        $text = trim(substr($string, $currentPos, $tagStartPos - $currentPos));
        if (!empty($text)) {
            $result[$currentPos] = $text;
        }
        // 进入<span>内部,更新当前位置到标签结束处
        $inSpan = true;
        $currentPos = $tagStartPos + $tagLength;
    } else {
        // 提取<span>标签内部的文本
        $text = trim(substr($string, $currentPos, $tagStartPos - $currentPos));
        if (!empty($text)) {
            $result[$currentPos] = $text;
        }
        // 退出<span>内部,更新当前位置到标签结束处
        $inSpan = false;
        $currentPos = $tagStartPos + $tagLength;
    }
}

// 处理最后一段(所有标签之后的剩余文本)
$finalText = trim(substr($string, $currentPos));
if (!empty($finalText)) {
    $result[$currentPos] = $finalText;
}

// 输出结果
print_r($result);
?>

代码解释

  1. 标签定位:用preg_match_all配合PREG_OFFSET_CAPTURE参数,获取所有<span>开始/结束标签的内容和它们在原字符串中的起始位置。
  2. 状态跟踪:用$inSpan变量标记当前是否处于<span>内部,以此区分要提取的是外部文本还是标签内部文本。
  3. 文本提取:每次遇到标签时,截取当前位置到标签起始位置之间的文本,trim()去除多余空白(如果不需要可以去掉),不为空则加入结果数组,键就是文本的起始位置$currentPos。
  4. 位置更新:每次处理完标签后,把$currentPos更新到标签结束的位置,确保下一次截取的是正确的文本段。
  5. 收尾处理:遍历完所有标签后,处理最后一段剩余的文本,避免遗漏。

输出结果

运行这段代码后,你会得到符合期望的数组结构:

Array
(
    [3] => i am a sentence
    [36] => im content inside of the span
    [79] => im another sentence
    [119] => i m another span content
    [166] => im the last sentence in this p tag
    [225] => im the third span tag in this p tag
)

内容的提问来源于stack exchange,提问作者Jevon McPherson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:46:44