[perl regex] вложенные блоки - как?

kruzer25

С какими ключами писать выражение, мб там ? куда-нибудь добавить, чтобы выражением /<.*>/s на строке <<>><> ловились подстроки 1-4 и 5-6, а не 1-3, не 1-6 итп...? Что-то я тут туплю совсем...
Хочется, чтобы выводом, например, preg_replace("/<(.*?)>/e","strlen('\\1')","<<>><>"); было 20, а не 4 и не 1>0, как выходит...
ЗЫ: Да, там, конечно, вместо < и > могут быть какие-то длинные (больше одного символа) строки, так что всякие там [^<^>] не подойдут в принципе.

kruzer25

Если что - пробовал /<(.*)>/, /<(.*?)>/, /<(.*)>/U, /<(.*?)>/U - всегда результат либо 4, либо 1>0...

kruzer25

Ещё несколько вариантов:
/<(.+?)>/ и /<(.+)>/U выдают 1><>
/<(.+)>/ и /<(.+?)>/U выдают 4
Если вместо . использовать [.], то результат всегда будет <0><>
<kz, но как мне получить 20?

Ivan8209

Ты пытаешься сделать ограниченную КС на РВ?
Тогда так и делай:
/<([^>]*)|([^>]*<[^<>]*>...)|(...)>/
Не проще ли взять что-нибудь более КС?
---
...Я работаю антинаучным аферистом...

kruzer25

Что есть КС? РВ, я так понимаю - "регулярные выражения"?
Твой вариант не подходит - как я уже сказал в первом посте, < и > я тут использую для большей наглядности, в реальной же жизни - вместо < и > некоторые (заранее неизвестные) регулярные выражения, произвольной длины (не обязательно 1).

Ivan8209

Пример.

$ echo '<<>><>' | sed 's/<[^<>]*<[^<>]*>[^<>]*>/n/'
n<>

---
...Я работаю антинаучным аферистом...

Ivan8209

"Контексто-свободный", -ая, -ое.
---
...Я работаю антинаучным аферистом...

kruzer25

Не понял.
Ладно, сформулирую чётче - надо, чтобы нечто типа
echo preg_replace("/preved(.*)medved/e","'['.strlen('\\1').']'","preved preved foo medved medved preved bar medved");
выводило
[19] [5]

Ivan8209

Я тебе про то и говорю: ты выбрал неудачное средство.
Ты хочешь разобрать КС язык с помощью РВ.
Это невозможно.
Это возможно с ограничением, что у тебя глубина вложения "скобок" не более наперёд заданой.
Соответственно:
0 --- '/[^<>]*/';
1 --- '/#0)<(#0)>)*(#0)/'
2 --- '/#1)<(#1)>)*(#1)/'
...
#n обозначает то РВ, что соответствует n-му шагу.
---
...Я работаю антинаучным аферистом...

kruzer25

Спасибо.
Уже сделал немного не так (на самом деле, в моей ситуации в некоторых случаях можно разбирать внутренние блоки до разбора внешних... и до разбора внешних блоков можно узнать, можно ли сейчас обработать конкретный внутренний блок) я с помощью РВ ищу все внутренние блоки (начало-текст-конец, где текст не содержит ни начало, ни конец для каждого из найденых блоков, если его можно обработать - обрабатываю, иначе - заменяю начало на начало2 и конец на конец2. После этого, начинаю обработку с начала - и так, пока есть, что менять.
Затем, если остались необработанные блоки (вида начало2-текст-конец2 заменяю начало2 на начало, конец2 на конец, и опять начинаю всю обработку.
Вроде бы, работает.
Что-то не хочется сейчас пытаться придумать систему блоков, на которой такой парсер повиснет.

rosali

Ты хочешь разобрать КС язык с помощью РВ.
Это невозможно.
Ну это всего лишь условность
На РВ можно написать лексер к этой граматике, а состояние хранить где-то в обычных перловых "статических" переменных.
Что-то наподобие
 m#(?:($re1?{$parser->f1($1)})|($re2?{$parser->f2($2)})|...)*#g; 

Ivan8209

> Ну это всего лишь условность
Ну, мы же не математики!
---
...Я работаю антинаучным аферистом...
Оставить комментарий
Имя или ник:
Комментарий: