Regex 如何使用正则表达式检查字符串是否与Oracle中的多个条件匹配?

Regex 如何使用正则表达式检查字符串是否与Oracle中的多个条件匹配?,regex,oracle,oracle10g,Regex,Oracle,Oracle10g,在与正则表达式搏斗之后,我想出了与此类单词匹配的模式^(ABC)\w*(\u USER[0-9]*)\w*(\u MOD\uw*) 如果字符串以ABC\uu开头,包含\u用户及其后的任何数字,并且在其后还包含单词\u MOD 匹配字符串的示例: ABC_sssss_USER0000000000_sssss_MOD_sssss ABC_SCssB_USER0332_MOD_REG_SP SELECT OBJECT_NAME, REGEXP_INSTR(OBJECT_NAME,

在与正则表达式搏斗之后,我想出了与此类单词匹配的模式
^(ABC)\w*(\u USER[0-9]*)\w*(\u MOD\uw*)

如果字符串以
ABC\uu
开头,包含
\u用户及其后的任何数字,并且在其后还包含单词
\u MOD

匹配字符串的示例:

ABC_sssss_USER0000000000_sssss_MOD_sssss

ABC_SCssB_USER0332_MOD_REG_SP
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 sql中工作

这是我的测试代码:

ABC_sssss_USER0000000000_sssss_MOD_sssss

ABC_SCssB_USER0332_MOD_REG_SP
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
结果:

ABC_sssss_USER0000000000_sssss_MOD_sssss

ABC_SCssB_USER0332_MOD_REG_SP
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
预期结果:

ABC_sssss_USER0000000000_sssss_MOD_sssss

ABC_SCssB_USER0332_MOD_REG_SP
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中如何实现这一点?

如果不强制使用正则表达式,您可以这样做,假设您在“\u 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
    );
对我来说,这比regexp版本(在12.1.0.1.0上)运行得快一点——大约占regexp版本所用时间的75%

如果在“\u 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
失败的原因仍然不清楚

我曾经在字符类中遇到过非拉丁语范围(如[A-z],但对于西里尔语,[А-Ø])由于NLS_排序设置而无法正常工作。也许类似的事情正在影响
\w

@simsim,请发布您的确切数据库版本和NLS设置,以便我们能够找到问题的根源,并使这个问题对其他人更有用

编辑:

ABC_sssss_USER0000000000_sssss_MOD_sssss

ABC_SCssB_USER0332_MOD_REG_SP
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

原因很简单-数据库版本
10.1
是罪魁祸首,10g中刚刚添加了regexp支持,而此版本中根本不支持
\w
。我的实例是
10.2
,以及“受perl影响的扩展”-请参阅,以获取添加内容的完整列表,并查看10.1中的可用内容。请注意,您也不支持非贪婪量词(
*?
+?
)或类似的字符类,如
\d

,只是为了澄清,
\u USER[0-9]*
将在
\u USER
后面匹配0或更多数字,因此
\u USER
\u USER1
也将匹配。如果您要查找数字,请将
*
替换为
+
@npinti,对于零位数或更多的用户,我可以接受。我认为您的预期结果有点不理想
ABC\U SCssB\U USER0332\U MOD\U REG\U SP
应为1,
ABC\U SCssB\U MOD\U REG\U SP
应为0。另外,我刚刚在我的oracle 10g实例上运行了您的逐字查询,它为ABC\U SCssB\U USER0332\U MOD\U REG\U SP
返回了1,为其他返回了0。看起来您的正则表达式正在工作,并且与ABC\U SCssB\U USER0332\U MOD\U REG\U SP匹配。它对我不起作用:\n嗯,我喜欢解决方法,谢谢。这就行了。但是,对于我来说,正则表达式函数为什么不起作用,为什么不给出错误,为什么在互联网上找不到关于这个问题的任何东西,甚至不需要翻译,OP说他对零位数或更多位数没问题,所以根本不需要检查它们。我很好奇为什么regexp不起作用,OP的DB配置似乎有问题。
SELECT*FROM nls\u session\u参数
返回了以下内容:
NLS\u LANGUAGE AMERICAN
NLS\u NCHAR\u字符集AL16UTF16
并且数据库版本是
Oracle database 10g Enterprise Edition Release 10.1.0.5.0-64bi
@simsim查看更新的答案,您只能使用有限的regexp支持