Ключевые слова:regex, perl, (найти похожие документы)
From: Anton Berezin <[email protected]>
Newsgroups: fido7.ru.cgi.perl
Date: 22 Jul 1999 19:16:41 +0400
Subject: Проверка сбалансированности скобок на Perl
>> Hачиная с 5.005 - уже можно. :-) Совpеменные Perl regexes - это
>> уже даже немножко больше, чем паpсеp контекстно-свободных языков.
>> Можно одним regexом написать паpсеp Си, напpимеp (только никто этого
>> ещё не сделал - слишком сложный regex получается :-)...
> Может я чайник? Пойду man читать... Hасколько мне помнится,
> классическаю теоpия pегэкспов (математическая) не пpедусматpивает
> никакой обpаботки вложенных стpуктуp. Лаppи Волл pазpаботал новую
> теоpию???
При чём тут теория? ``Немножко больше, чем парсер контекстно-свободных
языков'' - я это не зря написал. Очевидно, что классические регулярные
выражения могут парсить только лишь регулярные же языки. Просто
регулярные выражения в Perl не ограничиваются реализацией математических
регулярных выражений, а идут несколько дальше.
Вот, например, проверяет (в одной строке, и без какого-либо квотинга)
сбалансированность скобок (tested on 5.005_03):
#! /usr/bin/perl -w
sub match_parens
{
$_ = shift;
if ( m%^
(?{ $cnt = 0; })
(?:
\( (?{ local $cnt = $cnt + 1 })
|\) (?(?{ $cnt <= 0 })(?!)) (?{ local $cnt = $cnt - 1 })
|[^()]
)*
(?(?{ $cnt != 0 })(?!)) $%x)
{
print "Good: '$_'\n";
} else {
print "Bad : '$_'\n";
}
}
match_parens "";
match_parens ")";
match_parens "(";
match_parens "(((((())))))";
match_parens "sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) is a distance";
match_parens "((()()) (() )) ()";
match_parens "((()()) ((X )) ()";
__END__
А если сейчас начнутся крики, что, мол, не честно это - так я ж разве
спорю... :-) Можно, в одном регексе - вот что важно.