【问题标题】:regular expression to escape a single $ string正则表达式转义单个 $ 字符串
【发布时间】:2017-09-08 02:52:48
【问题描述】:

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

例如:RefinementFilter$$#$TAGS_AND$$#$karen.bitran - LAD_ODA_IB SE

上面的例子应该被拆分为 细化过滤器 TAGS_AND karen.bitran - LAD_ODA_IB SE

但是在遇到单个 $ 时,它会切断剩余的字符串部分并只给出字符串的一部分

细化过滤器 TAGS_AND karen.bitran - LAD_ODA_IB SE

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

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;

【问题讨论】:

  • 问题出在:^。请注意:\$\$\#\$ 只会找到这个确切的“东西”并忽略单个 $。我建议使用:regexr.com 它为调试您的正则表达式提供了很大的可能性

标签: sql regex oracle plsql


【解决方案1】:

在正则表达式中[] 表示单个字符匹配。所以[($$#$)] 将匹配单个字符( 或$ 或$ 或# 或$ 或) 并否定[^($$#$)] 将匹配任何不是@987654330 的字符@、$、# 或 )。

你可以不用正则表达式来做到这一点:

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;
/

【讨论】:

    猜你喜欢
    • 2010-09-21
    • 2011-10-13
    相关资源
    最近更新 更多