php preg_match_all需要多个结果

时间:2015-04-17 21:28:26

标签: php regex preg-match-all

我想让preg_match_all返回它找到的所有模式,即使已经使用了结果。以下示例隔离了问题。

$str = "whatever aaa 34567 aaa 56789 ll";
$pattern = '/.{0,100}\D[aaa]{3}\D{1}[0-9]{5}\D{1}/';
preg_match_all($pattern, $str, $amatches);
var_dump($amatches);

上面的结果返回一个数组元素。

0=>    `whatever aaa 34567 aaa 56789 `

我想要的是2个数组元素。

0=>    `whatever aaa 34567`   
1=>    `whatever aaa 34567 aaa 56789`  

2 个答案:

答案 0 :(得分:0)

这有点接近:

$str = "whatever aaa 34567 aaa 56789 ll";
$pattern = '/^((.*)\D[aaa]{3}\D{1}[0-9]{5}\D{1})?/';
preg_match($pattern, $str, $amatches);
var_dump($amatches);

返回

 array(3) { 
        [0] => string(29) "whatever aaa 34567 aaa 56789 " 
        [1] => string(29) "whatever aaa 34567 aaa 56789 " 
        [2] => string(18) "whatever aaa 34567" 
    }

或者这仍使用preg_match_all:

$str = "whatever aaa 34567 aaa 56789 ll";
$pattern = '/^((.*)\D[aaa]{3}\D{1}[0-9]{5}\D{1})?/';
preg_match_all($pattern, $str, $amatches);
var_dump($amatches);

我认为正在发生的事情是你的。{0,100}正在阅读整个事情而不允许正则表达式在最后开始。的?确保它以您的模式结束。

答案 1 :(得分:0)

以下是使用preg_replace_callback执行此任务的替代解决方案。

  • 查找匹配“任何字符后跟(并包括)三个'a'字符,一些空格和五个数字”的字符串。可能有尾随空格。 \b表示单词边界,阻止匹配“xaaa 12345”,“aaa 123456”或“aaa 12345xyz”
  • 将匹配的字符串连接到$soFar,其中包含以前匹配的所有字符串
  • 将该字符串附加到$result数组

我不太确定你是否希望“foo”和“bar”保留在字符串中,所以我就把它们留在了。

$str = "whatever foo aaa 12345 bar aaa 34567 aaa 56789 baz fez";

preg_replace_callback(
    '/.*?\baaa +\d{5}\b\s*/',
    function ($matches) use (&$result, &$soFar) {
        $soFar .= $matches[0];
        $result[] = trim($soFar);
    }, $str
);
print_r($result);

输出:

Array
(
    [0] => whatever foo aaa 12345 
    [1] => whatever foo aaa 12345 bar aaa 34567 
    [2] => whatever foo aaa 12345 bar aaa 34567 aaa 56789 
)

使用preg_match_allarray_map的两步版本:

preg_match_all('/.*?\baaa +\d{5}\b\s*/', $str, $matches);
$matches = array_map(
    function ($match) use (&$soFar) {
        $soFar .= $match;
        return trim($soFar);
    },
    $matches[0]
);
print_r($matches);