正则表达式以转义单个$ string

时间:2017-04-12 10:55:22

标签: sql regex oracle plsql

关于正则表达式,在下面的代码中,当遇到str ^ $$#$时它会拆分。但单一的$不应该改变它的分裂方式。

ex:RefinementFilter $$#$ TAGS_AND $$#$ karen.bitran - LAD_ODA_IB SE< $ 10K

上面的例子应该拆分为 细化滤波器TAGS_AND karen.bitran - LAD_ODA_IB SE< $ 10K

但是在遇到一个$时,它会删除剩余的字符串部分并只提供字符串的一部分

细化滤波器TAGS_AND karen.bitran - LAD_ODA_IB SE< 这是不可取的。

L_VALUE:= RefinementFilter $$#$ TAGS_AND $$#$ karen.bitran - LAD_ODA_IB SE>人力资源10万美元

WITH T AS
  (SELECT L_VALUE STR FROM DUAL
  )
SELECT MAX(DECODE(LEVEL,1,REGEXP_SUBSTR(STR,'[^($$#$)]+',1,LEVEL))) ,
  MAX(DECODE(LEVEL,2,REGEXP_SUBSTR(STR,'[^($$#$)]+',1,LEVEL))),
  MAX(DECODE(LEVEL,3,REGEXP_SUBSTR(STR,'[^($$#$)]+',1,LEVEL)))
INTO L_VAL1,
  L_VAL2,
  L_VAL3
FROM T
  CONNECT BY REGEXP_SUBSTR(STR,'[^($$#$)]+',1,LEVEL) IS NOT NULL;

1 个答案:

答案 0 :(得分:0)

在正则表达式[]中表示单个字符匹配。因此,[($$#$)]会匹配($$#$)的单个字符,否定[^($$#$)]可以匹配任何非($#)的字符。

您可以在没有正则表达式的情况下执行此操作:

DECLARE
  pattern VARCHAR2(10)   := '$$#$';
  l_value VARCHAR2(4000) := 'abc$$#$def$$#$gh$i';
  l_val1  VARCHAR2(200);
  l_val2  VARCHAR2(200);
  l_val3  VARCHAR2(200);
BEGIN
  WITH string_matches (str, match_start, match_end, lvl ) AS (
    SELECT l_value, 1, INSTR( l_value, pattern, 1 ), 1 FROM DUAL
  UNION ALL
    SELECT str,
           match_end + LENGTH( pattern ),
           INSTR( str, pattern, match_end + LENGTH( pattern ) ),
           lvl + 1
    FROM   string_matches
    WHERE  match_end > 0
  )
  SELECT str1, str2, str3
  INTO   L_VAL1, L_VAL2, L_VAL3
  FROM   string_matches
  PIVOT  ( MAX( SUBSTR(
                  str,
                  match_start,
                  DECODE( match_end, 0, LENGTH( str ) + 1, match_end ) - match_start
              ) )
           FOR lvl IN ( 1 AS str1, 2 AS str2, 3 AS str3 )
         );

  DBMS_OUTPUT.PUT_LINE( l_val1 );
  DBMS_OUTPUT.PUT_LINE( l_val2 );
  DBMS_OUTPUT.PUT_LINE( l_val3 );
END;
/

或者在纯PL / SQL中:

DECLARE
  TYPE stringlist IS TABLE OF VARCHAR2(200);
  pattern VARCHAR2(10)   := '$$#$';
  l_value VARCHAR2(4000) := 'abc$$#$def$$#$gh$i';
  matches stringlist := stringlist();
  match_start INTEGER := 1;
  match_end   INTEGER;
BEGIN
  LOOP
    match_end := INSTR( l_value, pattern, match_start );
    matches.EXTEND;
    IF match_end = 0 THEN
      matches( matches.COUNT ) := SUBSTR( l_value, match_start, LENGTH( l_value ) + 1 - match_start );
      EXIT;
    ELSE
      matches( matches.COUNT ) := SUBSTR( l_value, match_start, match_end - match_start );
    END IF;
    match_start := match_end + LENGTH( pattern );
  END LOOP;

  DBMS_OUTPUT.PUT_LINE( matches(1) );
  DBMS_OUTPUT.PUT_LINE( matches(2) );
  DBMS_OUTPUT.PUT_LINE( matches(3) );
END;
/