用于解构 SQL where 语句的正则表达式

问题描述 投票:0回答:2

寻找一个奇特的正则表达式来分割部分 SQL where 语句。旧版应用程序相当旧,下面的记录是手动输入的,这会出现很多错误。下面给出了我需要用括号将其分割的代码。我还需要记录逻辑运算符,以便在处理每个语句后我可以将其构造回来。

SQL where 场景:

my $view2 =“test1=1 AND ( test2=2 ) AND (test3=4 OR test3=9 OR test3=3 OR test3=5)”
预期数组:
1:“test1=1”
2:“test2=2”
3:“test3=4 OR test3=9 OR test3=3 OR test3=5”

my $view2 =“(test1 = 2 AND test2 = 1)或(test1 = 2 AND test2 = 6)OR(test1 = 2 AND test2 = 8)OR(test1 = 2 AND test2 = 10)”
预期数组:
1:“test1=2 AND test2=1”
2:“test1=2 AND test2=6”
3:“test1=2 AND test2=8”
4:“test1=2 AND test2=10 ”

我的$view3 =“test1 ='1'和test3 ='3'”
预期数组:
1:“test1 = '1' AND test3 = '3'”

我尝试将每个语句和逻辑分开,一个数组包含sql代码,另一个数组包含逻辑运算符。我还尝试了一个带有 sql 代码和逻辑运算符的数组。如果代码正确地包含在括号中,则所有内容都可以工作($view2),但如果不是,则该部分将被省略($view1 和 $view3)。

这就是我目前所拥有的

my $view1 = "test1=1 AND ( test2=2 ) AND (test3=4 OR test3=9 OR test3=3 OR test3=5)";
my $view2 = "( test1=2 AND test2=1 ) OR ( test1=2 AND test2=6 ) OR ( test1=2 AND test2=8 ) OR ( test1=2 AND test2=10 )";
my $view3 = "test1 = '1' AND test3 = '3'";

# stmt and logic separated
my @arr = ( $view1 =~ /\([^)]*\)/g );
my @logic= ( $view1 =~ /\)[^)]*\(/g );

# stmt and logic in one array
my @arrOne = $view =~ /\([^)]*[^(]*\)|\w+/g;


my $counter = 1;
foreach my $record (@arr) {
    $record =~ s/\( | \)//g;
    print "\n" . $counter . ":";
    print $record;
    $counter += 1;
}

my $counter_logic = 1;
foreach my $record (@logic) {
    $record =~ s/\) | \(//g;
    print "\n";
    print $record;
}

如何将不带括号的部分sql代码添加到正则表达式模式?不确定这是否可行?知道如何实现它吗?

sql regex perl
2个回答
0
投票

因此,在多次失败后,我决定使用 ChatGPT,无论你相信与否,代码似乎都可以工作。

首先我需要清除单引号和空格中的字符串,然后使用以下模式就可以了

my $pattern = qr/\b\w+\s*=\s*(?:'\w+'|\d+)\b|\(.*?\)/;
my @arr = $view =~ /$pattern/g;

0
投票

这不是一个完整的答案,而是一个策略的演示。您可以尝试预先解析输入语句以提取括号块,并用占位符替换它们。之后,解析其他语句应该很简单。并且利用原始字符串中的占位符,很容易重新组装它。

use strict;
use warnings;
use Data::Dumper;

my @data;
while (<DATA>) {
    my %block;
    my $count = 0;
    chomp;
    $block{original} = $_;
    while (s/\(([^)]+)\)/block$count/) {
        $block{"block$count"} = $1;
        $count++;
        if ($count > 100) {  # safety precaution
            warn "Too many blocks!"; last;
        }
    }
    $block{main} = $_;
    push @data, \%block;
}
print Dumper \@data;

__DATA__
test1=1 AND ( test2=2 ) AND (test3=4 OR test3=9 OR test3=3 OR test3=5)
( test1=2 AND test2=1 ) OR ( test1=2 AND test2=6 ) OR ( test1=2 AND test2=8 ) OR ( test1=2 AND test2=10 )
test1 = '1' AND test3 = '3'

输出:

$VAR1 = [
          {
            'main' => 'test1=1 AND block0 AND block1',
            'block0' => ' test2=2 ',
            'original' => 'test1=1 AND ( test2=2 ) AND (test3=4 OR test3=9 OR test3=3 OR test3=5)',
            'block1' => 'test3=4 OR test3=9 OR test3=3 OR test3=5'
          },
          {
            'block0' => ' test1=2 AND test2=1 ',
            'main' => 'block0 OR block1 OR block2 OR block3',
            'original' => '( test1=2 AND test2=1 ) OR ( test1=2 AND test2=6 ) OR ( test1=2 AND test2=8 ) OR ( test1=2 AND test2=10 )',
            'block1' => ' test1=2 AND test2=6 ',
            'block3' => ' test1=2 AND test2=10 ',
            'block2' => ' test1=2 AND test2=8 '
          },
          {
            'original' => 'test1 = \'1\' AND test3 = \'3\'',
            'main' => 'test1 = \'1\' AND test3 = \'3\''
          }
        ];
© www.soinside.com 2019 - 2024. All rights reserved.