我正在编写一个脚本来从文件中提取和转换SQL语句。我需要将sql unloaded froma gupta sqlbase数据库转换为SQLServer可以理解的sql。
一项任务是使用兼容名称替换不允许作为列名的关键字。
在下面的代码中,$ commands是一个包含sql语句的数组引用。 (这里实际上有更多的代码,但我提取它,因为它在这里不应该相关)
my @KeyWords = ("LEFT", "RIGHT", "PERCENT", "FILE", "PRINT", "CROSS", "PLAN", "TOP", "END", "FILE", "Default", "CHECK", "TEXT");
foreach $cmd (@$commands) {
foreach my $kw (@KeyWords) {
$cmd =~ s/\b$kw\b[^(]/_$kw/gi;
}
push @$converted, $cmd;
}
这适用于大多数语句,但在以下命令中"DEFAULT"
替换为"_DEFAULT
而不是"_DEFAULT"
。所以第二个引号就丢失了。
CREATE TABLE SYSADM.SUBTYPE ( ID_SUBTYPE INTEGER NOT NULL,
ID_TYPE INTEGER NOT NULL,
TYPE VARCHAR(1),
BEZEICH VARCHAR(60),
NUM_COLOR INTEGER,
NUM_TXTCOLOR INTEGER,
"DEFAULT" SMALLINT,
GENER_ARBA SMALLINT,
PROJEKTPLANUNG SMALLINT)
有没有办法修改正则表达式/ substition,这样就不会删除第二个引号?或者另一种方式?
答案 0 :(得分:3)
[^(]
匹配任何不是左开的paranthesis的单个字符。
您希望使用负零宽度前瞻断言:
s/\b$kw\b(?!\()/_$kw/gi;
(或者:(?![(])
)
您还可以将替换的字符添加回字符串:
s/\b$kw\b([^(])/_$kw$1/gi;
但请注意,这并不适用于所有情况。特别是如果关键字后面没有任何内容,则此模式将不匹配,而零宽度断言将为。