
本文介绍如何用 preg_match_all() 高效解析含省略号分隔的混排商品字符串,准确分离产品名称和对应价格,并提供可直接运行的正则模式、代码示例及关键注意事项。
本文介绍如何用 `preg_match_all()` 高效解析含省略号分隔的混排商品字符串,准确分离产品名称和对应价格,并提供可直接运行的正则模式、代码示例及关键注意事项。
在电商数据采集、日志清洗或爬虫结果处理中,常遇到类似以下格式的紧凑文本:
Galax RTX2060 1 Click 12GB OC .................729 GALAX GTX 1660 SUPER 1-CLICK OC 6GB ...679 GALAX RTX3050 8GB GDDR6 ......................450
目标是将每组「商品描述 + 省略号 + 价格」拆分为结构化键值对,例如:["Galax RTX2060 1 Click 12GB OC", "729"]、["GALAX GTX 1660 SUPER 1-CLICK OC 6GB", "679"] 等。
✅ 推荐方案:preg_match_all() + 精准正则
使用以下正则表达式可一次性匹配全部条目,并分别捕获名称与价格:
$input_lines = "Galax RTX2060 1 Click 12GB OC .................729 GALAX GTX 1660 SUPER 1-CLICK OC 6GB ...679 GALAX RTX3050 8GB GDDR6 ......................450";
// 核心正则:匹配「任意内容 + ≥3个连续点 + 价格(整数或小数)」
$pattern = '/\s*(.*?)\s*\.{3,}\s*(\d+(?:\.\d+)?)/';
preg_match_all($pattern, $input_lines, $matches, PREG_SET_ORDER);
// 结构化输出:每项为 [完整匹配, 名称, 价格]
$result = [];
foreach ($matches as $match) {
$result[] = [
'name' => trim($match[1]),
'price' => (float)$match[2]
];
}
print_r($result);
输出示例:
Array
(
[0] => Array
(
[name] => Galax RTX2060 1 Click 12GB OC
[price] => 729
)
[1] => Array
(
[name] => GALAX GTX 1660 SUPER 1-CLICK OC 6GB
[price] => 679
)
[2] => Array
(
[name] => GALAX RTX3050 8GB GDDR6
[price] => 450
)
)
? 正则详解
| 部分 | 含义 |
|---|---|
\s* |
匹配开头可能存在的空格/制表符(增强容错) |
(.*?) |
非贪婪捕获产品名称(直到遇到省略号前的空白) |
\s*\.{3,}\s* |
匹配 ≥3 个连续英文句点(...、....等),前后允许空白 |
(\d+(?:\.\d+)?) |
捕获价格:支持整数(450)和小数(699.99),(?:...) 为非捕获分组 |
⚠️ 注意事项
- ❌ 避免用
explode()或substr()手动切分:因省略号长度不固定(...vs................),且名称中可能含数字/空格,极易误切; - ❌ 不推荐
str_replace('.', ' ')后再explode(' '):会破坏产品名中的小数点(如“RTX3050.5”)、缩写(如“GDDR6.G”)或价格小数; - ✅ 若需兼容中文、特殊符号(如
®、™)或换行分隔,可在.*?中改用[\s\S]*?并启用s修饰符(/.../s); - ✅ 实际生产中建议添加价格校验(如
is_numeric($price) && $price > 0)防止脏数据。
? 总结
面对非结构化、靠视觉分隔符(如省略号)组织的文本,正则表达式是唯一可靠且可维护的解决方案。本例中的模式兼顾鲁棒性与可读性,可直接集成至数据清洗管道,无需预处理或多步字符串操作。











