Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Многоуровневая замена
Форумы портала PHP.SU » PHP » Регулярные выражения » Многоуровневая замена

Страниц (1): [1]
 

1. Roler - 20 Августа, 2009 - 16:18:10 - перейти к сообщению
Вообщем, я что-то не пойму, как сделать замену конструкции

на, допустим,


Заменяются только внешние теги, а как сделать так, чтобы заменились все?

P.S. Выражение
CODE (text):
скопировать код в буфер обмена
  1.  
  2. $text = preg_replace('#\[tag\](.*)\[\/tag\]#si', '<div class="tag">/1</div>', $text);
  3.  
2. Champion - 20 Августа, 2009 - 16:27:40 - перейти к сообщению
Или рекурсивная регулярка, или нежадная замена в цикле, пока есть, что заменять. Во втором случае это будет так по шагам:
1 - [tag][tag] [/tag][/tag]
2 -<tag>[tag] </tag>[/tag]
3 - <tag><tag> </tag></tag>
(Добавление)
нежадность задается опцией U
3. Roler - 20 Августа, 2009 - 17:37:45 - перейти к сообщению
Champion
Второй случай - это просто, понятно, но некрасиво.
Можно поподробнее про первый?
4. Champion - 20 Августа, 2009 - 17:41:05 - перейти к сообщению
Цитата:
Рекурсивные шаблоны
Рассмотрим задачу поиска соответствия со строкой, находящихся внутри неограниченного количества круглых скобок. Без использования рекурсии лучшее, что можно сделать - написать шаблон, который будет решать задачу для некоторой ограниченной глубины вложенности, так как обработать неограниченную глубину не предоставляется возможным. В Perl 5.6 предоставлены некоторые экспериментальные возможности, которые в том числе позвояляют реализовать рекурсию в шаблонах. Специально обозначение (?R) используется для указания рекурсивной подмаски. Таким образом, приведем PCRE шаблон, решающий поставленную задачу (подразумевается, что используется модификатор PCRE_EXTENDED, незначащие пробелы игнорируются): \( ( (?>[^()]+) | (?R) )* \)

Вначале он соответствует открывающей круглой скобке. Далее он соответствует любому количеству подстрок, каждая из которых может быть последовательностью не-скобок, либо строкой, рекурсивно соответствующей шаблону (т.е. строкой, корректно заключенной в круглые скобки). И, в конце, идет закрывающая круглая скобка.

Приведенный пример шаблона использует вложенные неограниченные повторения, поэтому использование однократных шаблонов значительно ускоряет процесс сопоставления, особенно в случаях, когда строка не соответствует заданной маске. Например, если его применить к строке: (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(), то несоответствие будет обнаружено достаточно быстро. Но в случае, если однократные шаблоны не используются, сопоставление будет затягиваться на длительное время, так как существует множество способов разделения строки между квантификаторами + и *, и все они должны быть проверены, прежде чем будет выдано сообщение о неудаче.

Значение, устанавливаемое для захватывающей подмаски будет соответствовать значению, захваченному на наиболее глубоком уровне рекурсии. В случае, если приведенный выше шаблон сопоставляется со строкой (ab(cd)ef), захваченным значением будет 'ef', которое является последним значением, принимаемым на верхнем уровне. В случае, если добавить дополнительные скобки \( ( ( (?>[^()]+) | (?R) )* ) \), захваченным значением будет "ab(cd)ef". В случае, если в шаблоне встречается более, чем 15 захватывающих скобок, PCRE требуется больше памяти для обработки рекурсии, чем обычно. Память выделяется при помощи функции pcre_malloc, и освобождается соответственно функцией pcre_free. Если память не может быть выделена, сохраняются данные только для первых 15 захватывающих скобок, так как нет способа выдать ошибку out-of-memory изнутри рекурсии.
5. Roler - 20 Августа, 2009 - 18:00:42 - перейти к сообщению
О Господи Не понял
Пойду разбирать это... Скобки слева в регулярке мне совершенно непонятны.
Спасибо.
6. Nestor - 20 Августа, 2009 - 18:10:17 - перейти к сообщению
А можно подробнее о ?R
7. Champion - 20 Августа, 2009 - 18:24:28 - перейти к сообщению
Roler пишет:
Пойду разбирать это... Скобки слева в регулярке мне совершенно непонятны.
Ну там для примера парсится строка со скобками. Это самая первая и самая последняя. \( и \). В начале регулярки идет утверждение, что после текущего место идет последовательность нескобок...
8. Roler - 20 Августа, 2009 - 18:30:44 - перейти к сообщению
А ?> это что такое?
9. Champion - 20 Августа, 2009 - 18:39:47 - перейти к сообщению
http://forum.php.su/topic.php?fo...=62&topic=30
10. Roler - 20 Августа, 2009 - 18:50:04 - перейти к сообщению
Champion
Там нет такого условия.
11. Champion - 20 Августа, 2009 - 18:53:05 - перейти к сообщению
Точно. Это то же, что (?=. Только употребляется с рекурсией. Хотя, если честно, я не углублялся в рекурсию и точно не могу сказать.

 

Powered by ExBB FM 1.0 RC1