Как написать регулярное выражение:
А вообще, от языка зависит.
/<>(.*)<--end menu-->/s
Никак.
<>qwqw<><>qawqw<>
/<>(.*?)<>/s
внутри кода может находится любое колво любых символовЧто-нибудь получим.
И что? Это ты вообще к чему?
Мне кажется что требуется совсем не это(я знаю что написано, просто мне это кажется очевидным). Это же не сферический конь в вакууме...
то в твоём случае мы на выходе получим массив $sub, в котором будут находиться все совпадения с паттерном (в данном случае их будет 2)
preg_match_all("/<>(.*?)<>/s",$text,$sub);
<><><>...<><><>
но это уже другой вопрос - можно ли написать парсер на регэкспах, и вроде выяснили, что нельзя
Ага. По лемме о накачке.
PS: я пытаюсь сказать что в терминах автора треда эту задачу решить нельзя. Нужно дать некие утверждения о том что может лежать внутри.
насколько я знаю автора, внутри лежит PHP-код, который не содержит вложенных блоков <>
Всем: а что мы получим на этом:Нужен "не жадный" режим. В перле он есть, не знаю как в других реализациях.
<>qwqw<><>qawqw<>
P.S. В случае вложенных, конечно, не получится.
Допустим существует HTML-документ, в котором произвольное число вложенных таблиц [<table>.*</table>]. Требуется "вырезать" по очереди самые вложенные таблицы (не содержащие внутри [<table>.*</table>] и, соответственно, выводить. И так - рекурсивно до конца вырезать изнутри всю таблицу. Ниже представлена программа, реализующая эту задачу при помощи логического оператора (?!...):
#!/usr/bin/perl -wT
$file=qq|s<table>aaa bbb
<table>cc<table>ccc
<table> 2<table>bb</table> <table>cc</table> </table></table>cc
</table>
ddd</table>d
|;
print $file;
&req($file);
sub req {
if($file=~m%(<table>?!.*<table>).*?)</table>)%igs){
$file=~s%(<table>?!.*<table>).*?)</table>)%%igs;
print "Virezali --$1--";
&req($file);
}
return $file;
}
http://genphys.phys.msu.ru/~dmitriyk/perl/regex.shtml#subroutines
PS: очевидно что программой это сделать можно. Прочти тред и пойми, что спрашивалось.
Так как мелких требований к функционалу никто и не додумался предъявить.
в конце концов если уж на принцип, то рекурсивно конструитровать к регекспе другой регекс, юзая eval какой нибудь.
конечно, тот код, который я привел - это более чем рег выражение...
p.s. не стоит недооцениватьперловые регекспы.
Это теоретически невозможно. Ботай автоматы.
А вот его сокращенный вид
#!/usr/bin/perl
$_=qq~
1234
34 -4567
3456
-0.35e-0,2
56grf45
-.034 E20
-.034 e2,01 -,045 e-,23
-,034 e201 3e-.20
-,045 e-,23 e-0.88
4 E-0.20
22
E-21
-0.2 w 4 3
345
2 ^-,3
~;
print "$1\n" while m%[+-]?(?=\d|[\.,]\d)\d*([\.,]\d*)?\se|e|\s?\^[-+]?\d*[,\.]?)\d+)?)|([+-]?e[+-]?\d*[,.]?\d+%gxi;
типа язык, который позволяет 63-мя символами реализовать 14 условий, хотя текст всего чистого регекспа - 39 символов. Ну понятно вобщем.
#!/usr/bin/perl
$_=qq~
1234
34 -4567
3456
-0.35e-0,2
56grf45
-.034 E20
-.034 e2,01 -,045 e-,23
-,034 e201 3e-.20
-,045 e-,23 e-0.88
4 E-0.20
22
E-21
-0.2 w 4 3
345
2 ^-,3
~;
$a='[+-]?\d*[,.]?\d+';print"$_\n"for/$a\s?[e^]$a|$a|[+-]?e$a/ig
Но в данном случае функциональные возможности языка программирования расширяют возможнсти автоматов, я так понял. И я походу дела имею ввиду возможности языка программирования но не возможности автоматов.
p.s. про недетерминированныфе и детерминированные конечные автоматы я только слышал как перл-программер, т.е. принципа их работы не знаю.
Вообще нельзя сделать рекурсию в regexp, но в perl можно.
#!/usr/bin/perl
sub qqq($) {
my $q = shift;
$q =~ s/(.*?)<begin.>(.*)<end.>(.*?)/$1.qqq($2).$3/e;
return $q;
}
print qqq("qwer<begin1>asd<end1>\n");
print qqq("<begin1>qwer<begin2>asd<end2>xyz<end1>\n");
Эта программа работает неправильно из-за бага (фичи?) в perl. При рекурсивном входе в блок переменные $1, $2, ... не очищаются. В этом можно убедиться вот так:
#!/usr/bin/perl
sub qqq($) {
my $q = shift;
print("oops: \$1 is - $1\n") if !($1 eq "");
print("oops: \$2 is - $2\n") if !($2 eq "");
print("oops: \$3 is - $3\n") if !($3 eq "");
$q =~ s/(.*?)<begin.>(.*)<end.>(.*?)/$1.qqq($2).$3/e;
return $q;
}
print qqq("qwer<begin1>asd<end1>\n");
print qqq("<begin1>qwer<begin2>asd<end2>xyz<end1>\n");
Если бы они очищались, то программа работала бы как надо.
#!/usr/bin/perl
sub qqq($;$$) {
my ($x, $q, $y);
if ($#{@_} == 0) { # first call
($x, $q, $y) = ("", shift, "");
} elsif ($#{@_} == 2) { # recursive call
($x, $q, $y) = @_;
} else {
die("oops\n");
}
$q =~ s/(.*?)<begin>(.*)<end>(.*?)/qqq($1,$2,$3)/e;
return $x.$q.$y;
}
print qqq("aaa<begin>qwer<begin>asd<end>xyz<end>bbb\n");
Вот вам пример кода..
(просто есть желание написать как нить попроще, не юзая темплейты)
<tr>задача - сделать так, что бы между коментами "menu" и "end menu" не осталось ничего...
<>
<td class="menu"><div align="left"><img alt="" src="image/super_shadow.jpg" height="25" width="190"></div>
<div class="menu">
<>
</div>
</td>
<>
<>
<td class="main">
Регэкспы надо юзать phpшные.
Если эти тэги не бывают вложенными, то решение уже тебе показали несколько раз. В самом начале треда.
Всем спасибо...
ЗЫ Уточнил задачу, что бы прекратить бесполезное гадание..
Всем участникам еще раз спасибо )
У XSLT по сравнению с регэкспами есть хотя бы то преимущество, что существенно снижается риск получить некорректный XML на выходе.
sub qqq($) {
my $q = shift;
$q =~ s/<begin>(.*)<end>/qqq($1)/e;
return $q;
}
print qqq("aaa<begin>qwer<begin>asd<end>xyz<end>bbb\n");
Эта программа работает неправильно из-за бага (фичи?) в perl. При рекурсивном входе в блок переменные $1, $2, ... не очищаются.В связи с этим открыт bug: http://rt.perl.org/rt3/index.html?q=34247
Имхо это не может быть багом по определению, так как семантика языка perl определена только его канонической реализацией.
Ты гонишь, потому что семантика определяется не реализацией, а документацией.
Документация определяет семантику частично.
Сорри, грубо вышло.
> Документация определяет семантику частично.
Возможно реализация определяет там, где промолчала документация. Но в данном случае баг стопудовый.
А вот хз. Всё-таки переменные специальные.
По твоей ссылке народ тоже не уверен, баг это или нет.
На документацию никто не ссылается, что характерно.
Только на интуицию, и на реализацию.
@- $-[0] is the offset of the start of the last successful match.
"$-["n"]" is the offset of the start of the substring matched
by n-th subpattern, or undef if the subpattern did not match.
Thus after a match against $_, $& coincides with "substr $_,
$-[0], $+[0] - $-[0]". Similarly, "$"n coincides with "substr
$_, $-["n"], $+["n"] - $-["n"]" if "$-["n"]" is defined, and $+
coincides with "substr $_, $-[$#-], $+[$#-]". One can use
"$#-" to find the last matched subgroup in the last successful
match. Contrast with $#+, the number of subgroups in the regu-
lar expression. Compare with "@+".
This array holds the offsets of the beginnings of the last suc-
cessful submatches in the currently active dynamic scope.
"$-[0]" is the offset into the string of the beginning of the
entire match. The nth element of this array holds the offset
of the nth submatch, so "$-[1]" is the offset where $1 begins,
"$-[2]" the offset where $2 begins, and so on.
Ок, убедил
Оставить комментарий
stm7884696
которое бы находило фрагмент кода между:<>
и
<>
(внутри кода может находится любое колво любых символов включая перенос строки)