0

我正在编写一个脚本来从文件中提取和转换 SQL 语句。我需要将从 gupta sqlbase 数据库中卸载的 sql 转换为 SQLServer 可以理解的 sql。

一项任务是将不允许作为列名的关键字替换为兼容的名称。

在下面的代码中,$commands 是一个包含 sql 语句的数组 ref。(实际上这里有更多代码,但我提取了它,因为它在这里不应该相关)

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)

有没有办法修改正则表达式/替换,这样就不会删除第二个引号?还是其他方式?

4

1 回答 1

3

[^(]匹配任何不是左左括号的单个字符。

您想改用负零宽度超前断言:

s/\b$kw\b(?!\()/_$kw/gi;

(或者(?![(]):)

您还可以将替换的字符添加回字符串:

s/\b$kw\b([^(])/_$kw$1/gi;

但请注意,这并非在所有情况下都有效。特别是如果关键字后面没有任何内容,则此模式将不匹配,而零宽度断言将匹配。

于 2013-08-07T11:57:23.713 回答