Perl Regex从Insert SQL中提取列名和值

时间:2016-11-17 12:36:41

标签: regex perl

有人可以帮助我在perl标量变量中获取提取列名称和值。

INSERT INTO MyTable (column1, column2, column3, column4, column5 ) VALUES (1, 'Hi', 'A,B', '', null)

结果因此我想将键和值存储在Map类型的变量中。

column1 1
column2 'Hi'
column3 'A,B'
column4 
column5 null

2 个答案:

答案 0 :(得分:3)

我不会用正则表达式来做这件事。 SQL是一种复杂的语言。重新发明轮子不是很聪明。我的方法使用SQL::Statement,这是许多DBI驱动程序使用的底层工具,它与实际上不是关系数据库的东西交互,比如DBD :: CSV。

它可以用来将SQL语句转换为数据结构,然后可以用它来查找你想要的内容。

use strict;
use warnings;
use SQL::Statement;
use List::MoreUtils 'zip';
use Data::Printer;

my $sql = q{INSERT INTO MyTable (column1, column2, column3, column4, column5) VALUES (1, 'Hi', 'A,B', '', null )};

my $parser = SQL::Parser->new;
my $stmt = SQL::Statement->new($sql, $parser);

my @col_names = map { $_->{value} } @{ $stmt->column_defs };
(my $tmp) = $stmt->row_values;
my @row_values = @$tmp;

my %pairs = zip @col_names, @row_values;
p %pairs;

输出结果为:

{
    column1   1,
    column2   "Hi",
    column3   "A,B",
    column4   "",
    column5   undef
}

请注意,字符串和裸字(缺少更好的名称)都被视为字符串。我还没弄明白为什么。

一般情况下,您必须阅读SQL::Statement::Structure以了解其工作原理。但值得注意的是,至少在我的1.407版本的SQL :: Statement中,事情与文档中的不同。 column_defs方法返回哈希引用,而那些不具有name项。文档的概要还允许人们假设column_defs返回的内容是哈希引用,而不是文档中进一步声称的对象。

无论如何,这种方法仍然有效。

答案 1 :(得分:1)

  

我想将结果以<key , value>格式存储在变量

然后你正在寻找hash

见下面的方法。

#!/usr/bin/perl
use strict;
use warnings;
use Data::Printer;

my $data = q!INSERT INTO MyTable (column1, column2, column3, column4, column5 ) VALUES (1, 'Hi', 'AB', '', null)!;
my %column_value_pair;

if ($data =~ m!\((.*)\).*VALUES.*\((.*)\)!g){
    my @columns = split /,/, $1;
    my @values = split /,/, $2;

    #remove leading and trailing spaces
    $_ =~ s/^\s+|\s+$//g foreach @columns, @values;

    @column_value_pair{@columns} = @values;
}

p %column_value_pair;

输出:

$ perl test.pl 
{
    column1   1,
    column2   "'Hi'",
    column3   "'AB'",
    column4   "''",
    column5   "null"
}

注意:我没有处理值包含逗号的情况,例如'A,B'。我把它作为练习留给你。提示:使用逗号作为分隔符拆分也会拆分A,B。