2011-03-08 2 views
3

У меня есть следующая строка, например:PHP Regexp (PCRE) - Найдите множество всех подстрок

aaXXccYYeeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZvv 

Как я могу найти все XX.*YY.*ZZ части в строке? (Возможно, с помощью preg_match())

  • ХХ куб.см ГГ eeXX_ ZZ
  • ХХ _ ZZkk ГГ mmXX _ ZZ
  • ХХ _ ZZnnXXoo YY uuXX _ ZZ
  • XX оо YY uuXX_ ZZ

Плюс все больше матчей, как:

  • XX куб.см YY eeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ Z Z
+1

Я столкнулся с тем же вопросом раньше. Проблема заключается в том, чтобы найти совпадающие, не жадные или не жадные работы самостоятельно. Однако я не эксперт по регулярному выражению. – Jacob

+0

Попробуйте использовать некоторые альтернативы исходного кода [RegexBuddy open source] (http://stackoverflow.com/questions/89718/is-there-anything-like-regexbuddy-in-the-open-source-world) для разработки шаблона соответствия. – mario

+0

Это похоже на этот вопрос: http://stackoverflow.com/questions/5163933/#5164444, но это было использование .Net, а не PCRE. – Kobi

ответ

2

Спасибо всем за помощь.

Мое решение на основе решения 'bobbogo'. Спасибо.

Регулярное выражение:

(?=(XX.*?YY.*?ZZ))(?=(.*ZZ)) 

Результат (от RegexBuggy):

1 XXccYYeeXX_ZZ  XXccYYeeXX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZ 
2 XX_ZZkkYYmmXX_ZZ  XX_ZZkkYYmmXX_ZZnnXXooYYuuXX_ZZ 
3 XX_ZZnnXXooYYuuXX_ZZ XX_ZZnnXXooYYuuXX_ZZ 
4 XXooYYuuXX_ZZ  XXooYYuuXX_ZZ 

Возможно это может более оптимизировать? Я не большой профессионал в регулярном выражении.

+0

Замечательно, что это отсортировано. Вы можете принять свой собственный ответ, нажав полый флажок рядом со стрелками вверх/вниз по этому ответу. –

1

Это кажется совершенно прямым на первый взгляд (извинения, если я чего-то не хватает). В первой части, использовать повторные матчи:

XX(.*?)YY(.*?)ZZ 

Для более длинного совпадения я предлагаю отдельный матч:

XX(.*?)YY(.*)ZZ 

EDIT

Aha! шаблоны перекрываются (спасибо людям). В этом случае вам придется перебирать петлю. Наверное, проще всего сбить любого ведущего .*?XX, прежде чем повторять попытку матча. В PERL земли вы будете использовать

while (/XX(.*?)YY(.*?)ZZ/) { 
    print "[$1] [$2]\n"; 
    s/^.*?XX//; 
} 

Если вы отчаянно для одного регулярного выражения, то m//g в контексте массива придет к вам на помощь. (Не уверен, что соответствующий PHP может выглядеть следующим образом.)

@a = /XX(?=(.*?YY.*?ZZ))/g; 

Массив @a будет содержать пересекающиеся строки, но с начальным XX отгоняют.

+0

У вас отсутствует что-то, что, на мой взгляд, ожидается, так как вопрос очень запутан - первый и второй результаты в примере перекрываются: 'XXYYXX_ZZYYZZ' должен давать * 2 * результаты:' XXYYXX_ZZ' и 'XX_ZZYYZZ'. Вы можете получить их с помощью '(? = XX (. *?) YY (. *?) ZZ)', но не для всех возможных длин или всех возможностей. – Kobi

Смежные вопросы