Шаблон поиска для логики декодирования - PullRequest
1 голос
/ 24 февраля 2020

Мне нужно декодировать logi c из базы данных, на которую я ссылаюсь при определении, может ли атрибут быть связан с элементом, который я определяю. База данных использует стандартную логику c потока и порядок важности. Мне нужно иметь возможность определять вложенные условные операторы в строках, которые я извлекаю из базы данных. Например:

$val = "(red && (blue || yellow)) && black";

Строка, которую я извлеку из базы данных, будет выглядеть так:

$pull = "red.yellow.black";

Я бы выделил $pull на . и сохранил бы значения в массиве тогда я бы проверил каждое значение в массиве (ах), которые я генерирую из строки $val. У меня проблемы с лучшим способом определения того, как распаковать вложенные логи c. Первоначально я рассмотрел использование регулярного выражения, а затем удалил часть логики c, которая была оценена следующим образом:

($eval) = $val =~ /.*\((.*)?\)/; $val =~ s/(.*)\((.*)?\)(.*)/$1 $2/;

Если я сделаю это в while ($val =~ /\(/) l oop, я Возможно, он мог бы сложить извлеченные логи c в массивы и оценить логическое выражение в каждом элементе, чтобы определить, выполняется ли каждое условие для элемента, который я оцениваю, но что-то не так с моим регулярным выражением, что приводит к сбою последовательности. ? не так ленив, как я думал, по-видимому ...

my $val = "(red && (blue || yellow)) && black";
my $pull = "red.yellow.black";
my @stack = ();

until ($val !~ /\(/) {
    my ($eval) = $val =~ /.*\((.*)?\)/;
    push(@stack, $eval);
    print "$eval\n";
    $val =~ s/(.+)\((.*)?\)(.*)/$1 $2/;
    print "$val\n";
}

Если я просто запускаю последовательность в оболочке perl с некоторой отладочной информацией, я получаю это:

[bin]$ perl -e 'my $val = "((red && (blue || yellow) && black)"; my $pull = "red.yellow.black"; my @stack = (); until ($val !~ /\(/) { my ($eval) = $val =~ /.*\((.+)?\).?/; push(@stack, $eval); print "EVAL: $eval\n";$pause = <STDIN>;$val =~ s/(.*)\((.*)?\)(.*)/$1 $2/;print "VAL: $val\n"; }'
EVAL: blue || yellow) && black

VAL: ((red &&  blue || yellow) && black
EVAL: red &&  blue || yellow

VAL: ( red &&  blue || yellow
EVAL:

Любая информация о том, что я делаю неправильно, будет принята с благодарностью, и любые улучшения эффективности будут высоко оценены! TIA

Обновление: Хорошо, поэтому я просто ошарашил все это так. Я теряю некоторые из порядка операций, но если я оцениваю каждое утверждение индивидуально, всякий раз, когда одно из условий нарушается, я подберу его и смогу действовать в соответствии с информацией. Код, который я собираюсь расширить, приведен ниже. Это просто вернуло бы отдельные компоненты выражения. Мне не нравится, как все круглые скобки объединяются в первый элемент, но я думаю, что это по-прежнему работает принципиально.

my $val = "(red && (blue || yellow)) && black";
$val =~ s/\s+//g;

my @chars = ();
my @ops = ();

while ($val) {
    my ($char) = $val =~ /(.)/;
    $val =~ s/.//;
    push @chars, $char;
}

my $index = 0;
foreach my $char (@chars) {
    if ($char =~ /\(/) {
        $index++;
    } elsif ($char =~ /\)/) {
        $index--
    }
    #assign the character to the index.
    $ops[$index] .= $char;
}

s/[()]//g for @ops;
print " @ops\n";

Вывод:

[/bin]$ perl decode_logic.pl
 &&black red&& blue||yellow
...