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

含HTML的数字分组格式化:正则表达式问题求助

解决方案

方法一:通过数字偏移量分步分割(推荐)

这种方法先提取所有数字在原字符串中的位置,再按位置直接分割,完全忽略中间的HTML代码,逻辑清晰且不易出错:

$inputStr = "你的目标字符串,包含任意HTML和数字,比如:前缀<b>1</b>2<div>3</div>45<em>6789</em>01234后缀内容";

// 提取所有数字及其在字符串中的偏移量
preg_match_all('/\d/', $inputStr, $digitMatches, PREG_OFFSET_CAPTURE);
$digitCount = count($digitMatches[0]);

// 先检查数字数量是否满足要求
if ($digitCount < 13) {
    die("错误:字符串中的数字数量不足13个");
}

// 提取对应数字的偏移量(数组索引从0开始,第3个数字对应索引2,以此类推)
$offsets = [
    2 => $digitMatches[0][2][1],   // 第3个数字的偏移量
    4 => $digitMatches[0][4][1],   // 第5个数字的偏移量
    6 => $digitMatches[0][6][1],   // 第7个数字的偏移量
    10 => $digitMatches[0][10][1], // 第11个数字的偏移量
    12 => $digitMatches[0][12][1]  // 第13个数字的偏移量
];

// 按偏移量分割字符串为指定的6组
$groups = [
    substr($inputStr, 0, $offsets[2]),                                  // 组1:第3个数字前的所有文本
    substr($inputStr, $offsets[2], $offsets[4] - $offsets[2]),          // 组2:第3至第5个数字前的文本
    substr($inputStr, $offsets[4], $offsets[6] - $offsets[4]),          // 组3:第5至第7个数字前的文本
    substr($inputStr, $offsets[6], $offsets[10] - $offsets[6]),         // 组4:第7至第11个数字前的文本
    substr($inputStr, $offsets[10], $offsets[12] - $offsets[10]),       // 组5:第11至第13个数字前的文本
    substr($inputStr, $offsets[12])                                     // 组6:第13个数字到末尾的文本
];

// 输出结果示例
foreach ($groups as $idx => $content) {
    echo "组" . ($idx + 1) . ": " . htmlspecialchars($content) . "\n";
}

方法二:使用正则表达式一次性捕获分组

如果偏好正则写法,可以用带有正向预查的正则来精准定位数字位置,忽略中间的HTML:

$inputStr = "你的目标字符串,包含任意HTML和数字,比如:前缀<b>1</b>2<div>3</div>45<em>6789</em>01234后缀内容";

// 检查数字数量
preg_match_all('/\d/', $inputStr, $digitMatches);
if (count($digitMatches[0]) < 13) {
    die("错误:字符串中的数字数量不足13个");
}

// 构建正则模式,使用正向预查定位目标数字位置
$pattern = '/^
    (.*?)                  # 组1:开头到第3个数字前
    (?=(?:\D*\d){2}\D*\d) # 预查:匹配前2个数字(含中间非数字/HTML)+ 第3个数字
    (\D*\d.*?)             # 组2:第3个数字到第5个数字前
    (?=(?:\D*\d){1}\D*\d) # 预查:匹配第4个数字(含中间非数字/HTML)+ 第5个数字
    (\D*\d.*?)             # 组3:第5个数字到第7个数字前
    (?=(?:\D*\d){1}\D*\d) # 预查:匹配第6个数字(含中间非数字/HTML)+ 第7个数字
    (\D*\d.*?)             # 组4:第7个数字到第11个数字前
    (?=(?:\D*\d){3}\D*\d) # 预查:匹配第8-10个数字(含中间非数字/HTML)+ 第11个数字
    (\D*\d.*?)             # 组5:第11个数字到第13个数字前
    (?=(?:\D*\d){1}\D*\d) # 预查:匹配第12个数字(含中间非数字/HTML)+ 第13个数字
    (\D*\d.*)$             # 组6:第13个数字到末尾
/sx';

preg_match($pattern, $inputStr, $matches);
array_shift($matches); // 移除整个匹配的完整字符串,保留6个分组

// 输出结果示例
foreach ($matches as $idx => $content) {
    echo "组" . ($idx + 1) . ": " . htmlspecialchars($content) . "\n";
}

关键说明

  1. 两种方法都先检查数字数量,避免因数字不足导致的错误
  2. 方法一中的PREG_OFFSET_CAPTURE标记用于获取每个数字在原字符串中的精确位置,确保分割准确
  3. 方法二中的\D匹配任意非数字字符(包括HTML标签、空格、符号等),(?:\D*\d)用于跳过“任意非数字+一个数字”的组合,精准定位目标数字的位置
  4. 正则中的s修饰符让.匹配换行符,x修饰符允许正则中添加空白,提升可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:54:49