Oracle REGEXP_SUBSTR无法使用我的模式

时间:2016-05-03 12:10:36

标签: sql regex oracle10g

我有以下查询:

SELECT DISTINCT A.REZ FROM
(
  SELECT REGEXP_SUBSTR(P_EQUATION, '([A-Z|a-z|0-9]+)\{([0-9|\+|\-| |\*|\/\)\(]+)\}#([A-Z|a-z|0-9|_]+)#',1, LEVEL) AS REZ FROM DUAL
  CONNECT BY REGEXP_SUBSTR(P_EQUATION, '([A-Z|a-z|0-9]+)\{([0-9|\+|\-| |\*|\/\)\(]+)\}#([A-Z|a-z|0-9|_]+)#',1, LEVEL) IS NOT NULL
) A;

如果我提供了以下输入:

P_EQUATION := 'A123{(01+02)*2}#ACCOUNT_BALANCE# + B123{(20+10)/20}#ACCOUNT_BALANCE#';

它给了我以下内容:

REZ
-------------------------------------
A123{(01+02)*2}#ACCOUNT_BALANCE#
B123{(20+10)/20}#ACCOUNT_BALANCE#

但是,虽然减号包含在模式中,但如果我将其添加到花括号内,它将不再识别文本作为匹配!

例如:

P_EQUATION := 'A123{(01-02)*2}#ACCOUNT_BALANCE#';

我无法找到解决方案,这让我感到非常震惊,尤其是当我尝试单独使用减号时,如果我尝试单独匹配数字,它也能正常工作:(

2 个答案:

答案 0 :(得分:1)

Oracle似乎正在使用POSIX样式的正则表达式:https://docs.oracle.com/cd/B12037_01/server.101/b10759/ap_posix001.htm#i690819

  

反斜杠不是POSIX括号表达式中的元字符。所以在POSIX中,正则表达式[\d]匹配\d

     

> http://www.regular-expressions.info/posixbrackets.html

反斜杠可能搞乱了,而且他们没有必要。你也没有意识到|是一个char类中的文字(评论也指出了这一点)。我已经修复了这些问题,并将-移动到char类的开头,这允许它被解释为文字。

你走了:

([A-Za-z0-9]+)\{([-0-9+ */)(]+)\}#([A-Za-z0-9_]+)#

答案 1 :(得分:1)

无法弄清楚代码的问题,但这是一种方法:

with temp as
(
  select 'A123{(01+02)*2}#ACCOUNT_BALANCE# + B123{(20+10)/20}#ACCOUNT_BALANCE#' P_EQUATION from dual union all
  select 'A123{(01-02)*2}#ACCOUNT_BALANCE#' P_EQUATION from dual
)

SELECT DISTINCT A.REZ FROM
(
  SELECT REGEXP_SUBSTR(P_EQUATION, '[[:alpha:]]+[[:digit:]]+{\([[:digit:]]+\S[[:digit:]]+\)\S[[:digit:]]+}#[[:alpha:]]+_[[:alpha:]]+#',1, LEVEL) AS REZ FROM temp
  CONNECT BY REGEXP_SUBSTR(P_EQUATION, '[[:alpha:]]+[[:digit:]]+{\([[:digit:]]+\S[[:digit:]]+\)\S[[:digit:]]+}#[[:alpha:]]+_[[:alpha:]]+#',1, LEVEL)  IS NOT NULL
) A;

输出:

REZ                                                                                                                                                                                                                                                                            
---------------------------------------
B123{(20+10)/20}#ACCOUNT_BALANCE#                                                                                                                                                                                                                                                
A123{(01-02)*2}#ACCOUNT_BALANCE#                                                                                                                                                                                                                                                 
A123{(01+02)*2}#ACCOUNT_BALANCE#