You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则拆解SQL WHERE语句?适配无括号场景需求

问题

现有遗留系统中,SQL WHERE语句为手动录入,存在较多格式问题。需使用正则表达式拆分该语句,既要处理带括号的子句,也要兼容无括号的部分,同时需记录逻辑运算符以便后续重构语句。当前尝试的正则仅能识别带括号的内容,无法处理无括号场景(如$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语句部分?

解决方案

要同时匹配带括号的子句和无括号的原子条件,需调整正则逻辑,核心是先匹配完整的括号子句,再匹配无括号的条件,同时单独提取逻辑运算符。

核心正则调整

  • 提取条件子句:使用/\([^()]*\)|[^()\sANDOR]+(?:\s*=\s*[^()\sANDOR]+)?/g
    拆解:
    • \([^()]*\):匹配非嵌套的括号子句
    • [^()\sANDOR]+(?:\s*=\s*[^()\sANDOR]+)?:匹配无括号的条件,允许等号前后带空格(如test1 = '1')
  • 提取逻辑运算符:使用/\b(AND|OR)\b/g
    拆解:通过单词边界确保匹配完整的AND/OR,避免误匹配其他字符串中的子串

修改后完整代码

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'";

# 批量处理所有视图
foreach my $view ($view1, $view2, $view3) {
    print "\n=== 处理当前视图 ===";
    # 提取所有条件子句
    my @conditions = $view =~ /\([^()]*\)|[^()\sANDOR]+(?:\s*=\s*[^()\sANDOR]+)?/g;
    # 提取所有逻辑运算符
    my @operators = $view =~ /\b(AND|OR)\b/g;

    # 清理条件子句的冗余格式
    my $counter = 1;
    foreach my $cond (@conditions) {
        $cond =~ s/^\s*\(|\)\s*$//g; # 移除前后括号及周围空格
        $cond =~ s/\s+/ /g; # 合并多余空格
        print "\n$counter: $cond";
        $counter++;
    }

    # 输出逻辑运算符
    print "\n逻辑运算符:";
    print " $_" foreach @operators;
    print "\n";
}

扩展说明

  • 如果需要支持嵌套括号,可将条件子句正则替换为递归版本:/\((?:[^()]|(?R))*\)|[^()\sANDOR]+(?:\s*=\s*[^()\sANDOR]+)?/g,即可匹配多层嵌套的括号子句
  • 代码中加入了格式清理逻辑,能处理手动录入的空格混乱问题,输出更规整

内容的提问来源于stack exchange,提问作者niebyl2002

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:26:27