这是一个简单的问题,但我浪费了太多时间试图自己解决。
我将数据存储在字符串中,r{N}-{N}s{N}
其中 {N} 是一位或两位数。这种模式最多可以重复 5 次。我需要从模式中提取数字,最好以某种方式分组。
例如,如果字符串是"r4-10s5"
,我想提取{4,10,5}
如果字符串是"r4-10s5r6-7s8"
我想提取{4,10,5} {6,7,8}
我怎么能在 PHP 中完成这项工作?
我曾尝试使用递归正则表达式,但我无法让它们正确匹配。
静态模式是:r -
s
,空点只能是数字
/r(\d{1,2})-(\d{1,2})s(\d{1,2})/
=> 在这里测试:http ://regex101.com/r/sH4sY0
\d{1,2}
连续匹配 1 或 2 个数字
$str = "r4-10s5r6-7s8";
preg_match_all("#r(\d{1,2})-(\d{1,2})s(\d{1,2})#", $str, $matches);
// group the matches together
$sets = array();
for ($i = 0, $count = count($matches[0]); $i < $count; $i++)
$sets[] = array($matches[1][$i], $matches[2][$i], $matches[3][$i]);
print_r($sets);
输出:
array (size=2)
0 =>
array (size=3)
0 => string '4' (length=1)
1 => string '10' (length=2)
2 => string '5' (length=1)
1 =>
array (size=3)
0 => string '6' (length=1)
1 => string '7' (length=1)
2 => string '8' (length=1)
没有循环的另一个选项是:
preg_match_all("#r(\d{1,2})-(\d{1,2})s(\d{1,2})#", $str, $matches, PREG_SET_ORDER);
print_r($matches);
输出:
array (size=2)
0 =>
array (size=4)
0 => string 'r4-10s5' (length=7)
1 => string '4' (length=1)
2 => string '10' (length=2)
3 => string '5' (length=1)
1 =>
array (size=4)
0 => string 'r6-7s8' (length=6)
1 => string '6' (length=1)
2 => string '7' (length=1)
3 => string '8' (length=1)
我会这样做:
function extractNumbers($string, $multiples = 3, $strict = false) {
$string = preg_replace('/\D+/', ' ', trim($string));
$array = explode(' ', trim($string));
$count = count($array);
$remove = ($count % $multiples);
if ($remove > 0) {
// Strict, do not allow dangling numbers
if ($strict) {
return null;
}
$array = array_slice($array, 0, ($count - $remove));
}
$array = array_map('intval', $array);
return array_chunk($array, $multiples);
}
$str = 'r4-10s5r6-7s8';
var_dump(extractNumbers($str));
它可能不是很优雅,但相对容易理解和维护。