недавно я столкнулся со странной ошибкой при использовании динамических регулярных выражений в perl для совпадения в скобках.Исходная строка: "{... test {...} ...}", я хочу получить пару скобок, начинающихся с test, "test {...}".на самом деле, вероятно, есть много пар скобок до и до конца этой группы, я не знаю, насколько они глубоки.
Ниже приведены мои сценарии соответствия: nesting_parser.pl
#! /usr/bin/env perl
use Getopt::Long;
use Data::Dumper;
my %args = @ARGV;
if(exists$args{'-help'}) {printhelp();}
unless ($args{'-file'}) {printhelp();}
unless ($args{'-regex'}) {printhelp();}
my $OpenParents;
my $counts;
my $NestedGuts = qr {
(?{$OpenParents = 0})
(?>
(?:
[^{}]+
| \{ (?{$OpenParents++;$counts++; print "\nLeft:".$OpenParents." ;"})
| \} (?(?{$OpenParents ne 0; $counts++}) (?{$OpenParents--;print "Right: ".$OpenParents." ;"})) (?(?{$OpenParents eq 0}) (?!))
)*
)
}x;
my $string = `cat $args{'-file'}`;
my $partten = $args{'-regex'} ;
print "####################################################\n";
print "Grep [$partten\{...\}] from $args{'-file'}\n";
print "####################################################\n";
while ($string =~ /($partten$NestedGuts)/xmgs){
print $1."}\n";
print $2."####\n";
}
print "Regex has seen $counts brackts\n";
sub printhelp{
print "Usage:\n";
print "\t./nesting_parser.pl -file [file] -regex '[regex expression]'\n";
print "\t[file] : file path\n";
print "\t[regex] : regex string\n";
exit;
}
На самом деле мое регулярное выражение:
our $OpenParents;
our $NestedGuts = qr {
(?{$OpenParents = 0})
(?>
(?:
[^{}]+
| \{ (?{$OpenParents++;})
| \} (?(?{$OpenParents ne 0}) (?{$OpenParents--})) (?(?{$OpenParents eq 0} (?!))
)*
)
}x;
Я добавил счетчик скобок в nesting_parser.pl
Я также пишу генератор строк для отладки: gen_nesting.pl
#! /usr/bin/env perl
use strict;
my $buffer = "{{{test{";
unless ($ARGV[0]) {print "Please specify the nest pair number!\n"; exit}
for (1..$ARGV[0]){
$buffer.= "\n\{\{\{\{$_\}\}\}\}";
#$buffer.= "\n\{\{\{\{\{\{\{\{\{$_\}\}\}\}\}\}\}\}\}";
}
$buffer .= "\n\}}}}";
open TEXT, ">log_$ARGV[0]";
print TEXT $buffer;
close TEXT;
Вы можете сгенерировать тестовый файл с помощью
./gen_nesting.pl 1000
Он создаст файл журнала с именем log_1000, который включает 1000 пар скобок
Теперь мы тестируем наши сценарии сопоставления:
./nesting_parser.pl -file log_1000 -regex "test" > debug_1000
debug_1000 выглядит как великолепный идеальный результат, успешно сопоставленный!Но когда я генерирую файл журнала теста на 4000 строк и снова сопоставляю его, он кажется сбойным:
./gen_nesting.pl 4000
./nesting_parser.pl -file log_4000 -regex "test" > debug_4000
Конец debug_4000 показывает
{{{{3277}
####
Regex has seen 26213 brackts
Я не знаю, что не так свыражения регулярных выражений, в основном это работает хорошо для парных скобок, до недавнего времени я обнаружил, что это происходит сбой при попытке сопоставить текстовый файл длиной более 600 000 строк.
Я действительно смущен этими проблемами, я действительно надеюсь, чторешить эту проблему.
спасибо всем!