php 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`  

person user3757731    schedule 17.04.2015    source источник


Ответы (2)


Вот альтернативное решение с использованием 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_all и array_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);
person mhall    schedule 24.04.2015
comment
Спасибо, это именно то, что мне нужно. Я немного повозился с вашим решением, чтобы получить именно то, что мне нужно. $ pattern = '/.{0,7}\baaa\W{1,3}\d{5}\b\s*/i'; что позволит следующей строке появиться 3 раза. $ str = все, что угодно, foo -aaa, 12345 foo aaa, 34567 aaa, 56789 baz fez; - person user3757731; 26.04.2015

это немного ближе:

$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} читается целиком, не позволяя регулярному выражению сработать в конце вообще. ? Убедитесь, что он заканчивается вашим рисунком.

person dgig    schedule 17.04.2015
comment
Спасибо, dgig, вроде работает, однако, если я расширю его, как показано ниже, теперь должно быть 3 отдельных элемента массива, которые он не расширяет. Мне также нужен шаблон для ограничения значения в начале, потому что он готовится из файла. $ str = whever1 aaa 12345 xx независимо от типа aaa 34567 aaa 56789 ll; Результат 0 = ›string 'whever1 aaa 12345 xx независимо от aaa 34567 aaa 56789' 1 =› string 'whever1 aaa 12345 xx независимо от aaa 34567 aaa 56789' 2 = ›строка 'whever1 aaa 12345 xx независимо от aaa 34567' (длина = 39) - person user3757731; 19.04.2015
comment
Я не уверен, но это сайт, на котором вы можете проверить свое регулярное выражение, он действительно помог мне многому научиться: regex101 .com - person dgig; 20.04.2015
comment
как насчет этого? $ pattern = '/ [aaa] {3} [0-9] {5} /'; - person dgig; 20.04.2015
comment
Спасибо, dgig, $ pattern = '/ \ D [aaa] {3} \ D {1} [0-9] {5} \ D /' выдаст 3 результата с $ str = whever1 aaa 12345 xx независимо от того, что aaa 34567 aaa 56789 ll будет отображено только 2 результата с $ str = whever1 aaa 12345 xx независимо от aaa 34567 aaa 56789 ll Это связано с дополнительным пробелом между 34567 и aaa. Таким образом, остается вопрос, как вывести все результаты независимо от того, что было найдено. - Гленн - person user3757731; 22.04.2015