Oracle REGEXP_SUBSTR 不支持我的模式
Oracle REGEXP_SUBSTR not working with my pattern
我有以下查询:
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#';
我找不到解决这个问题的方法,这让我很害怕,尤其是当我尝试单独匹配减号时它有效,如果我尝试单独匹配数字它也有效 :(
Oracle 似乎正在使用 POSIX 风格的正则表达式:https://docs.oracle.com/cd/B12037_01/server.101/b10759/ap_posix001.htm#i690819
The backslash is NOT a metacharacter in a POSIX bracket expression. So in POSIX, the regular expression [\d]
matches a \
or a d
反斜杠可能会把它搞砸,而且它们不是必需的。您也没有意识到 |
是 char class 中的文字(评论也指出了这一点)。我已经解决了这些问题,并将 -
移到了字符 class 的开头,这样就可以将其解释为文字。
给你:
([A-Za-z0-9]+)\{([-0-9+ */)(]+)\}#([A-Za-z0-9_]+)#
无法完全找出您的代码的问题,但这是一种解决方法:
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#
我有以下查询:
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#';
我找不到解决这个问题的方法,这让我很害怕,尤其是当我尝试单独匹配减号时它有效,如果我尝试单独匹配数字它也有效 :(
Oracle 似乎正在使用 POSIX 风格的正则表达式:https://docs.oracle.com/cd/B12037_01/server.101/b10759/ap_posix001.htm#i690819
The backslash is NOT a metacharacter in a POSIX bracket expression. So in POSIX, the regular expression
[\d]
matches a\
or ad
反斜杠可能会把它搞砸,而且它们不是必需的。您也没有意识到 |
是 char class 中的文字(评论也指出了这一点)。我已经解决了这些问题,并将 -
移到了字符 class 的开头,这样就可以将其解释为文字。
给你:
([A-Za-z0-9]+)\{([-0-9+ */)(]+)\}#([A-Za-z0-9_]+)#
无法完全找出您的代码的问题,但这是一种解决方法:
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#