为什么regexp_replace什么都不替换?

时间:2015-03-06 20:44:50

标签: regex oracle oracle10g

我必须更新几个脚本才能使用另一个模式中的表: S1.MYTABLE =>的 S2.MYTABLE2

当我替换表的名称时,我想保留原始脚本的格式。如果 S1.MYTABLE

之后有 S2.MYTABLE2 ,请保持输入或空格

我的代码似乎工作正常,但在字符串结尾处串行 S2.MYTABLE2

这是我的测试脚本 :(这只是我问题的简化示例)

DECLARE
   testtext VARCHAR2(2000) := 'CREATE OR REPLACE FUNCTION "S1"."MY_FUNCTION" (PARAMETER1 VARCHAR2)
   RETURN VARCHAR2
AS
   something1    VARCHAR2 (50);
   OUTsomething   VARCHAR2 (50);
BEGIN
   BEGIN
      SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE_RELATED
       WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE
       WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;

   SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE                                  
        WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;
END;';

   script CLOB;
   owner VARCHAR2(30) := 'S1';
   object_name VARCHAR2(30) := 'MYTABLE';
   output_name VARCHAR2(30) := 'MYTABLE2';
   destination VARCHAR2(30) := 'S2';

BEGIN

        script := regexp_replace(testtext, OWNER || '[[:space:]]*\.[[:space:]]*' || OBJECT_NAME || ' ', DESTINATION || '.' || OUTPUT_NAME || ' ',1, 0, 'i');
        script := regexp_replace(script, OWNER || '[[:space:]]*\.[[:space:]]*' || OBJECT_NAME || '\s|($)', DESTINATION || '.' || OUTPUT_NAME || CHR(13) || CHR(10),1, 0, 'i');                
        DBMS_OUTPUT.PUT_LINE(script);                    
END;

函数MY_FUNCTION的代码虽然不切实际,但却是我正在处理的所有案例的例证。

运行此脚本的结果:

CREATE OR REPLACE FUNCTION "S1"."MY_FUNCTION" (PARAMETER1 VARCHAR2)
   RETURN VARCHAR2
AS
   something1    VARCHAR2 (50);
   OUTsomething   VARCHAR2 (50);
BEGIN
   BEGIN
      SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE_RELATED
       WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S2.MYTABLE2
       WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S2.MYTABLE2 WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;

   SELECT COLUMN1
        INTO OUTsomething
        FROM S2.MYTABLE2                                  
        WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;
END;S2.MYTABLE2

如您所见, S1.MYTABLE 已被所有相关位置的 S2.MYTABLE2 取代,维持原始格式(空格并输入)。

但由于某种原因 S2.MYTABLE2 在最后连接。

为什么regexp_replace在脚本末尾连接S2.MYTABLE2?

有没有更好的方法来实现我的目标?将表格换成另一个表格,保留格式。

2 个答案:

答案 0 :(得分:1)

这是问题所在:

\s|($)

表示交替匹配,最终将用新文本替换字符串锚点的结尾。我想你想要这个:

(\s|$)

答案 1 :(得分:1)

可能是因为第二个正则表达式中的|($)。不知道为什么你想要它。

删除 -

DECLARE
   testtext      VARCHAR2 (2000)
      := 'CREATE OR REPLACE FUNCTION "S1"."MY_FUNCTION" (PARAMETER1 VARCHAR2)
   RETURN VARCHAR2
AS
   something1    VARCHAR2 (50);
   OUTsomething   VARCHAR2 (50);
BEGIN
   BEGIN
      SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE_RELATED
       WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE
       WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;

   SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE                                  
        WHERE COLUMN2 = ''xx'' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;
END;';

   script        CLOB;
   owner         VARCHAR2 (30) := 'S1';
   object_name   VARCHAR2 (30) := 'MYTABLE';
   output_name   VARCHAR2 (30) := 'MYTABLE2';
   destination   VARCHAR2 (30) := 'S2';
BEGIN
   script      :=
      REGEXP_REPLACE (
         testtext,
         OWNER || '[[:space:]]*\.[[:space:]]*' || OBJECT_NAME || ' ',
         DESTINATION || '.' || OUTPUT_NAME || ' ',
         1,
         0,
         'i');
   script      :=
      REGEXP_REPLACE (
         script,
         OWNER || '[[:space:]]*\.[[:space:]]*' || OBJECT_NAME || '\s',
         DESTINATION || '.' || OUTPUT_NAME || CHR (13) || CHR (10),
         1,
         0,
         'i');
   DBMS_OUTPUT.PUT_LINE (script);
END;

这是最后没有表名的输出 -

CREATE OR REPLACE FUNCTION "S1"."MY_FUNCTION" (PARAMETER1 VARCHAR2)
   RETURN VARCHAR2
AS
   something1    VARCHAR2 (50);
   OUTsomething   VARCHAR2 (50);
BEGIN
   BEGIN
      SELECT COLUMN1
        INTO OUTsomething
        FROM S1.MYTABLE_RELATED
       WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S2.MYTABLE2
       WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;

       SELECT COLUMN1
        INTO OUTsomething
        FROM S2.MYTABLE2 WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;

   SELECT COLUMN1
        INTO OUTsomething
        FROM S2.MYTABLE2                                  
        WHERE COLUMN2 = 'xx' AND COLUMN2 = PARAMETER1;                                           
   RETURN OUTsomething;
END;

编辑:您可能想要做@ DavidFaber的答案,以防您的正则表达式模式也可能出现在整个字符串的末尾(而不仅仅是一行的结尾)。