如何使用正则表达式检查字符串是否匹配 Oracle 中的多个条件?
How to check if a string matches multiple conditions in Oracle using regular expressions?
在与正则表达式斗争之后,我想出了这个匹配这种词的模式^(ABC_)\w*(_USER[0-9]*)\w*(_MOD_)\w*
如果字符串以ABC_
开头,包含_USER with any number following it
,后面还包含_MOD_
这个词
匹配字符串示例:
ABC_sssss_USER0000000000_sssss_MOD_sssss
ABC_SCssB_USER0332_MOD_REG_SP
在此工具中测试:
http://www.regexpal.com/
但我无法在 oracle 中使用它 sql
这是我的测试代码:
SELECT
OBJECT_NAME,
REGEXP_INSTR(OBJECT_NAME, '^(ABC_)\w*(_USER[0-9]*)\w*(_MOD_)\w*') AS IS_MATCH
FROM
(
SELECT 'ABC_SCssB_USER0332_MOD_REG_SP' OBJECT_NAME FROM DUAL UNION
SELECT 'ABC_SCssB_USER0332_REG_SP' FROM DUAL UNION
SELECT 'SCssB_USER0332_MOD_REG_SP' FROM DUAL UNION
SELECT 'ABC_SCssB_MOD_REG_SP' FROM DUAL
)
结果:
ABC_SCssB_MOD_REG_SP 0
ABC_SCssB_USER0332_MOD_REG_SP 0
ABC_SCssB_USER0332_REG_SP 0
SCssB_USER0332_MOD_REG_SP 0
预期结果:
ABC_SCssB_MOD_REG_SP 0
ABC_SCssB_USER0332_MOD_REG_SP 1
ABC_SCssB_USER0332_REG_SP 0
SCssB_USER0332_MOD_REG_SP 0
我如何在 oracle 中实现它?
如果不强制使用正则表达式,您可以这样做,假设您在“_USER”之后需要一位或多位数字:
select
object_name,
case when translate(OBJECT_NAME, '#0123456789', ' ##########')
like 'ABC\_%\_USER#%\_MOD\_%' escape '\'
then 1
else 0
end as is_match
from
(
select 'ABC_SCssB_USER0332_MOD_REG_SP' object_name from dual union
select 'ABC_SCssB_USER0332_REG_SP' from dual union
select 'SCssB_USER0332_MOD_REG_SP' from dual union
select 'ABC_SCssB_MOD_REG_SP' from dual
);
这对我来说比正则表达式版本(在 12.1.0.1.0 上)运行得快一点 - 大约是正则表达式版本所用时间的 75%。
如果“_USER”后可以有 0 位或更多位数字,则可以这样做:
select
object_name,
case when OBJECT_NAME like 'ABC\_%\_USER%\_MOD\_%' escape '\'
then 1
else 0
end as is_match
from
(
select 'ABC_SCssB_USER0332_MOD_REG_SP' object_name from dual union
select 'ABC_SCssB_USER0332_REG_SP' from dual union
select 'SCssB_USER0332_MOD_REG_SP' from dual union
select 'ABC_SCssB_MOD_REG_SP' from dual
);
好的,事实证明,如果将 \w*
更改为 .*
,它会起作用。不过,目前还不清楚是什么原因导致 \w
失败。
我曾经遇到过 non-latin 字符 类 范围(如 [A-z] 但对于西里尔文 [А-я])无法正常工作,因为 NLS_SORT 设置。也许类似的事情正在影响 \w
?
@simsim,请 post 您的确切数据库版本和 NLS 设置,以便我们可以尝试找到问题的根源并使这个问题对其他人更有用。
编辑:
事实证明原因要简单得多 - 数据库版本 10.1
是罪魁祸首,10g 中刚刚添加了正则表达式支持,而此版本根本不支持 \w
。我的实例是 10.2
和 "perl-influenced extensions" were only added in 10.2 - see this table for a full list of things that were added, and this link 以查看 10.1 中可用的内容。请注意,您也不支持 non-greedy 量词(.*?
、.+?
)或类似字符 类,如 \d
。
在与正则表达式斗争之后,我想出了这个匹配这种词的模式^(ABC_)\w*(_USER[0-9]*)\w*(_MOD_)\w*
如果字符串以ABC_
开头,包含_USER with any number following it
,后面还包含_MOD_
这个词
匹配字符串示例:
ABC_sssss_USER0000000000_sssss_MOD_sssss
ABC_SCssB_USER0332_MOD_REG_SP
在此工具中测试: http://www.regexpal.com/
但我无法在 oracle 中使用它 sql
这是我的测试代码:
SELECT
OBJECT_NAME,
REGEXP_INSTR(OBJECT_NAME, '^(ABC_)\w*(_USER[0-9]*)\w*(_MOD_)\w*') AS IS_MATCH
FROM
(
SELECT 'ABC_SCssB_USER0332_MOD_REG_SP' OBJECT_NAME FROM DUAL UNION
SELECT 'ABC_SCssB_USER0332_REG_SP' FROM DUAL UNION
SELECT 'SCssB_USER0332_MOD_REG_SP' FROM DUAL UNION
SELECT 'ABC_SCssB_MOD_REG_SP' FROM DUAL
)
结果:
ABC_SCssB_MOD_REG_SP 0
ABC_SCssB_USER0332_MOD_REG_SP 0
ABC_SCssB_USER0332_REG_SP 0
SCssB_USER0332_MOD_REG_SP 0
预期结果:
ABC_SCssB_MOD_REG_SP 0
ABC_SCssB_USER0332_MOD_REG_SP 1
ABC_SCssB_USER0332_REG_SP 0
SCssB_USER0332_MOD_REG_SP 0
我如何在 oracle 中实现它?
如果不强制使用正则表达式,您可以这样做,假设您在“_USER”之后需要一位或多位数字:
select
object_name,
case when translate(OBJECT_NAME, '#0123456789', ' ##########')
like 'ABC\_%\_USER#%\_MOD\_%' escape '\'
then 1
else 0
end as is_match
from
(
select 'ABC_SCssB_USER0332_MOD_REG_SP' object_name from dual union
select 'ABC_SCssB_USER0332_REG_SP' from dual union
select 'SCssB_USER0332_MOD_REG_SP' from dual union
select 'ABC_SCssB_MOD_REG_SP' from dual
);
这对我来说比正则表达式版本(在 12.1.0.1.0 上)运行得快一点 - 大约是正则表达式版本所用时间的 75%。
如果“_USER”后可以有 0 位或更多位数字,则可以这样做:
select
object_name,
case when OBJECT_NAME like 'ABC\_%\_USER%\_MOD\_%' escape '\'
then 1
else 0
end as is_match
from
(
select 'ABC_SCssB_USER0332_MOD_REG_SP' object_name from dual union
select 'ABC_SCssB_USER0332_REG_SP' from dual union
select 'SCssB_USER0332_MOD_REG_SP' from dual union
select 'ABC_SCssB_MOD_REG_SP' from dual
);
好的,事实证明,如果将 \w*
更改为 .*
,它会起作用。不过,目前还不清楚是什么原因导致 \w
失败。
我曾经遇到过 non-latin 字符 类 范围(如 [A-z] 但对于西里尔文 [А-я])无法正常工作,因为 NLS_SORT 设置。也许类似的事情正在影响 \w
?
@simsim,请 post 您的确切数据库版本和 NLS 设置,以便我们可以尝试找到问题的根源并使这个问题对其他人更有用。
编辑:
事实证明原因要简单得多 - 数据库版本 10.1
是罪魁祸首,10g 中刚刚添加了正则表达式支持,而此版本根本不支持 \w
。我的实例是 10.2
和 "perl-influenced extensions" were only added in 10.2 - see this table for a full list of things that were added, and this link 以查看 10.1 中可用的内容。请注意,您也不支持 non-greedy 量词(.*?
、.+?
)或类似字符 类,如 \d
。