PHP Regexp (PCRE) - Найти набор всех подстрок 2 - PullRequest
0 голосов
/ 11 марта 2011

Например, есть исходная строка:

__aaXXccYYeeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZvv..

Как мне найти все: aaXX * YY * ZZ

__ aaXX cc YY eeXX_ ZZ kkYYmmXX_ZZnnXXooYYuuXX_ZZvv ..

__ aaXX cc YY eeXX_ZZkkYYmmXX_ * 101 * * zv * * * * * * * * * * * * * * * *

__ aaXX куб.см ГГ eeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ ZZ vv ..

__ aaXX 10ZKXYXXXXXXX* mmXX_ ZZ nnXXooYYuuXX_ZZvv ..

1037 * __ AAXX ccYYeeXX_ZZkk YY mmXX_ZZnnXXooYYuuXX_ ZZ ст .. 1045* __ aaXX ccYYeeXX_ZZkkYYmmXX_ZZnnXXoo YY uuXX_ ZZ vv ..

Проблема в том, что PHP preg не поддерживает? + * (Переменнаядлина) в (? <= exp) утверждении с задним числом (разрешено только с фиксированной длиной {N}). </p>

Поэтому необходимо решение без использования утверждения с заданной длиной с изменяемой длиной.

Спасибо!

Ответы [ 3 ]

1 голос
/ 11 марта 2011

Вам нужно зациклить. Сначала ищите __aaXX, затем следующий YY, затем __aaXX, затем второй YY и т. Д. В регулярном выражении это означает, что вы сначала ищите __aaXX(.*?YY){1}, затем __aaXX(.*?YY){2} (вы можете увидеть цикл там переменная?) и так до тех пор, пока не выйдет шаблон То же самое для второй части, когда вы ищете ZZ s.

1 голос
/ 11 марта 2011

Этот скрипт работает:

<?php // test.php 20110311_1200
    $data = '__aaXXccYYeeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZvv..';
    $all_matches = array();
    $yy_match = true; // Get past first for test condition.
    for ($yy_cnt = 1; $yy_match; ++$yy_cnt) {
        $yy_match = false; // Assume failure for this yy_cnt.
        $zz_match = true; // Get past first for test condition.
        for ($zz_cnt = 1; $zz_match; ++$zz_cnt) {
            $zz_match = false; // Assume failure for this zz_cnt.
            // Assemble new regex with new $yy_cnt and $zz_cnt.
            $re = "/ # Match all combinations of XX..YY..ZZ.
                (aaXX)                   # $1: Prefix X.
                (?:                      # Group to find YY[yy_cnt].
                  (?:(?!YY).)*           # Zero or more non-YY.
                  (YY)                   # $2: next YY.
                ){{$yy_cnt}}             # yy_cnt.
                (?:                      # Group to find ZZ[zz_cnt].
                  (?:(?!ZZ).)*           # Zero or more non-ZZ.
                  (ZZ)                   # $3 next ZZ.
                ){{$zz_cnt}}             # $zz_cnt.
                /x";
            if (preg_match($re, $data, $matches, PREG_OFFSET_CAPTURE)) {
                $zz_match = true;
                $yy_match = true;
                $all_matches[] = $matches;
                printf("Match found. \$yy_cnt = %d, \$zz_cnt = %d\n",
                    $yy_cnt, $zz_cnt);
            }
        }
    }
    print_r($all_matches);
?>
0 голосов
/ 11 марта 2011

Как насчет этого шаблона: # aaXX(.*) YY (.*) ZZ .*#?

Из вашего выделения не совсем ясно, как должен выглядеть ваш результат ... Я добавил пробелы, потому что они есть в выделении, но не ясно, есливы будете иметь их в своем источнике ...

Редактировать

Я полагаю, я не понимаю, что вы хотите получить, но еще одна вещь, чтобы посмотреть на этоpreg_match_all, если ваша часть YY ZZ повторяется ... Что-то вроде #_aaXX((.*?)YY(.*?)ZZ)+#.

...