LINUX.ORG.RU

разбор регулярками PCRE (Perl-style)


0

0

Привет,
надо разбивать на составляющие выражения вида:
A=B&A=(F|D)|G=J
т.е. хочется чтобы получилось
A=B
&
A=(F|D)
|
G=J
но затруднение в том, что я не могу заставить его игноировать | внутри скобок, т.е. у меня пока осилилось только
/([\&\|])/
для которого все разделители одинаковы

★★★★★

Ответ на: комментарий от wfrr

ну регекспами как-то красивше и лаконичнее получается, собственно они на автоматах вроде и работают, просто кривой нечитабельный велик не хочется делать.

Syncro ★★★★★
() автор топика

Регулярных выражений не хватит, чтобы пропарсить скобки произвольной вложенности. Делай КС-грамматику и парсер из неё, или просто руками напиши, это будет проще.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

> Регулярных выражений не хватит, чтобы пропарсить скобки произвольной вложенности.

Но их более чем достаточно для разделения такого выражения на лексемы.

> но затруднение в том, что я не могу заставить его игноировать | внутри скобок

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

anonymous
()

Для таких задач prolog подходит хорошо

anonymous
()
Ответ на: комментарий от anonymous

$str = "A=B&A=(F|D)|G=J";

@str = ( );
$parlevel = 0;
$curpiece = undef;
foreach $token (split(/([()&|])/, $str)) {
	if($token eq '(') {
		$parlevel++;
		$curpiece .= $token;
	} elsif($token eq ')') {
		$parlevel--;
		$curpiece .= $token;
	} elsif(($token eq '&' || $token eq '|') && !$parlevel) {
		if(defined($curpiece)) {
			push(@str, $curpiece);
			undef $curpiece;
		}
		push(@str, $token);
	} else {
		$curpiece .= $token;
	}
}
push(@str, $curpiece) if defined $curpiece;

print join(", ", map("\"$_\"", @str));
print "\n";

anonymous
()

Скобки вложенные? Если да - то это не регулярная грамматика; PCRE 
такое, вообще говоря, парсят, но медленно и странно. Используй 
генератор парсеров какой-нибудь, либо делай лексинг регекспами, а потом
склеивай обратно тупейшим стековым парсером.

Если скобки бывают только одни - то как-то так:

$ echo 'A=B&A=(F|D)|G=J' | perl -ne 'chomp; print "$_\n" foreach /(?:^|[|&])(\w+=(?:\([^)]+\)|[^(][^|&]*))/g;'
A=B
A=(F|D)
G=J

anonymous
()
Ответ на: комментарий от anonymous

я подумываю об том чтобы сделать со вложенными, но убрать неоднозначные конструкции вроде A=(F|D)

Syncro ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.