PHP如何提取字符串末尾所有以@开头或纯数字的空格分隔片段
最优实现方案
方案1:单行正则匹配(性能最优)
直接通过正则匹配字符串末尾连续符合规则的所有词,无需拆分遍历,代码最简洁:
$str = 'hello @tag1 111 world @tag2 @tag3 222 333'; preg_match('~(?:@\S+|\d+)(?:\s+(?:@\S+|\d+))*$~', trim($str), $match); $result = $match[0] ?? ''; echo $result;
正则逻辑说明
(?:@\S+|\d+):匹配单个符合规则的词,要么@开头后跟非空字符,要么全是数字(?:\s+(?:@\S+|\d+))*:匹配0个或多个「空格+符合规则的词」的组合$:限制匹配必须到字符串末尾,保证只取末尾连续的符合规则的序列- 提前用
trim()处理字符串首尾空格,避免边界问题
方案2:简化版数组遍历(可读性更高)
如果你偏好数组处理的方式,可以简化原来的逻辑,不需要额外存储待删除索引,直接从后往前遍历找到第一个不符合规则的位置即可:
$str = 'hello @tag1 111 world @tag2 @tag3 222 333'; $words = preg_split('~\s+~', trim($str)); $lastInvalidIndex = -1; // 从后往前找第一个不符合规则的词的索引 for ($i = count($words) - 1; $i >= 0; $i--) { if (!preg_match('~^(?:@\S+|\d+)$~', $words[$i])) { $lastInvalidIndex = $i; break; } } $result = implode(' ', array_slice($words, $lastInvalidIndex + 1)); echo $result;
优势说明
- 用
preg_split拆分替代explode,自动处理多个连续空格的边界问题 - 最坏情况下仅需要遍历1次数组,比原方案存储所有待删除索引的逻辑更省内存
输出效果
两种方案对示例输入的输出均为:
@tag2 @tag3 222 333
内容的提问来源于stack exchange,提问作者Mr Eblis
相关产品推荐
相关产品推荐

