[英]Converter Perl script fix
I am trying to use a small Perl script in order to convert SQL INSERT statements from MySQL syntax into SQLite syntax. 我试图使用一个小的Perl脚本,以便将SQL INSERT语句从MySQL语法转换为SQLite语法。 But the script has a bug and can't convert the string constants properly in some corner cases. 但是该脚本有一个错误,在某些特殊情况下无法正确转换字符串常量。
Here is the script: 这是脚本:
#!/usr/bin/perl
while (<>){
s/\\'/''/g; # Use '' instead of \'
s/\\"/"/g; # Use " instead of \"
s/\\r\\n/\r\n/g; # Convert escaped \r\n to literal
s/\\\\/\\/g; # Convert escaped \ to literal
s/ auto_increment//g; # Remove auto_increment
s/^[UN]*?LOCK TABLES.*//g; # Remove locking statements
print;
}
The problem is that in the case of the following MySQL string: 问题是在以下MySQL字符串的情况下:
'It doesn\'t work :-\\'
It generates wrong SQLite string: 它生成错误的SQLite字符串:
'It doesn''t work :-\''
instead of the proper: 而不是适当的:
'It doesn''t work :-\'
What is wrong in the script? 脚本有什么问题?
EDIT: 编辑:
And how to fix it? 以及如何解决?
It's because you're processing \\'
before \\\\
. 这是因为您要在\\\\
之前处理\\'
。 You need to handle backslashes in the order they are encountered, so you need to do everything in one pass. 您需要按遇到的顺序处理反斜杠,因此您需要一次性完成所有操作。
#!/usr/bin/perl
my %escapes = (
n => "\n",
r => "\r",
);
while (<>) {
s{\\([\Wrn])}{ $escapes{$1} // ( $1 eq "'" ? "''" : $1 ) }eg;
s/ auto_increment//g;
next if /^(?:UN)?LOCK TABLES/;
print;
}
Note the proper way of optionally matching UN
. 请注意可选地匹配UN
的正确方法。
The first substitution s/\\\\'/''/g;
第一个替换s/\\\\'/''/g;
replace the last \\'
by ''
, so 用''
替换最后一个\\'
''
,所以
'It doesn\'t work :-\\'
# ^^
becomes 变成
'It doesn\'t work :-\''
I guess you want to replace \\'
only when it is not followed by a non-word character \\W
. 我猜您只想在不带非单词字符\\W
后才替换\\'
。
I'm using here only the 2 relevant substitutions for this case 我在这里只使用2种相关替换
my $str = <<'EOD';
insert into tbl values ('it doesn\'t work :-\\', 42, 33, 'and this doesn\'t work as well :-\\', 1024);
EOD
say "before: ",$str;
$str =~ s/\\'(?!\W)/''/g;
$str =~ s/\\\\/\\/g;
say "after: ",$str;
Output: 输出:
before: insert into tbl values ('it doesn\'t work :-\\', 42, 33, 'and this doesn\'t work as well :-\\', 1024);
after: insert into tbl values ('it doesn''t work :-\', 42, 33, 'and this doesn''t work as well :-\', 1024);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.