вторник, 11 января 2011 г.

Perl и динамические регулярные выражения

Нашёл тут у себя старый код, который решал интересную задачу поиска произвольно вложенных конструкций с помощью регулярных выражений. Эх! За что люблю Perl, так это за то что в нём такие мощные regexp'ы. Решение было подсмотрено в книге Дж.Фридла "Регулярные выражения" и называется это решение "Динамические регулярные выражения".

Regexp для проверки правильности вложенности скобок в строке текста выглядит вот так

my $regex;
$regex = qr/ (?:[^()]+ | \( (??{ $regex }) \) )* /x;

if ( $text =~ m/$regex/ ) {
    print "строка валидна\n";
}


Так вот... Динамические регулярные выражения обычно применяются для поиска вложенных конструкций с произвольным уровнем вложенности. Регулярное выражение в данном случае рекурсивно обрабатывает конструкции любого уровня вложенности. Как и написано в книге будем использовать объект регулярного выражения и будем ссылаться на него с помощью конструкции вида (??{ $regex })

А теперь маленький пример perl скрипта, определяющего правильность расстановки скобок

#!/usr/bin/perl

use strict;

my @list = qw/
 (a+b)
 ()(123)()(())
 (()111)
 ))((
 ())(()
 ((((()))))))))(((((((((
 (((((((((
 )))))))))))
 ()()()()()()()()()))))(((((
 ((()))()(())((((()()))))
 (((((())()((())))))))
 123
/;

my $regex;
$regex = qr/ (?:[^()]+ | \( (??{ $regex }) \) )* /x;

for my $str ( @list ) {
 my $tmp = $str;
 $tmp =~ s/$regex//g;
 printf "%-30s\tresult %-20s\t", $str, $tmp;
 print $tmp ? "error!\n" : "is valid\n";
}

Комментариев нет:

Отправить комментарий