寻找一个奇特的正则表达式来分割部分 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代码添加到正则表达式模式?不确定这是否可行?知道如何实现它吗?
因此,在多次失败后,我决定使用 ChatGPT,无论你相信与否,代码似乎都可以工作。
首先我需要清除单引号和空格中的字符串,然后使用以下模式就可以了
my $pattern = qr/\b\w+\s*=\s*(?:'\w+'|\d+)\b|\(.*?\)/;
my @arr = $view =~ /$pattern/g;
这不是一个完整的答案,而是一个策略的演示。您可以尝试预先解析输入语句以提取括号块,并用占位符替换它们。之后,解析其他语句应该很简单。并且利用原始字符串中的占位符,很容易重新组装它。
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\''
}
];