PL / SQL:字符串的regexp_like不以字母开头

时间:2013-12-19 17:32:10

标签: regex oracle plsql

对于在Oracle数据库11g上运行的regexp_like。我想要一个模式来匹配一个不以AM或AP开头的字符串,字符串通常是几个字母,后跟下划线和其他字母或下划线。 例如:

字符串:AM_HTCEVOBLKHS_BX [false]
字符串:AP_HTCEVOBLKHSPBX [false]
字符串:BM_HTCEVOBLKHS_BX [true]
字符串:A_HTCEVODSAP_DSSD [true]
字符串:A_HTCEVOB_A_CDSED [true]
字符串:MP_HTCEVOBLKHS_BX [true]

你能制作这种模式吗?

我目前的解决方案不起作用:

BEGIN
    IF regexp_like('AM_HTCEVOBLKHS_BX','[^(AM)(AP)]+_.*') THEN
        dbms_output.put_line('TRUE');
    ELSE
        dbms_output.put_line('FALSE');
    END IF;
END;
/

4 个答案:

答案 0 :(得分:1)

为什么你需要regexp为什么你不使用简单的substr?

with t1 as
 (select 'AM_HTCEVOBLKHS_BX' as f1
    from dual
  union all
  select 'AP_HTCEVOBLKHSPBX'
    from dual
  union all
  select 'BM_HTCEVOBLKHS_BX'
    from dual
  union all
  select 'A_HTCEVODSAP_DSSD'
    from dual
  union all
  select 'A_HTCEVOB_A_CDSED'
    from dual
  union all
  select 'MP_HTCEVOBLKHS_BX' from dual
  union all
  select null from dual
  union all
  select '1' from dual)

select f1,
       case
           when substr(f1, 1, 2) in ('AM', 'AP') then
            'false'
           else
            'true'
       end as check_result
  from t1

答案 1 :(得分:1)

如果你有一个模式表,那么:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE strings ( string ) AS
          SELECT 'AM_HTCEVOBLKHS_BX' FROM DUAL
UNION ALL SELECT 'AP_HTCEVOBLKHSPBX' FROM DUAL
UNION ALL SELECT 'BM_HTCEVOBLKHS_BX' FROM DUAL
UNION ALL SELECT 'A_HTCEVODSAP_DSSD' FROM DUAL
UNION ALL SELECT 'A_HTCEVOB_A_CDSED' FROM DUAL
UNION ALL SELECT 'MP_HTCEVOBLKHS_BX' FROM DUAL;

CREATE TABLE patterns ( pattern ) AS
          SELECT '^AM' FROM DUAL
UNION ALL SELECT '^AP' FROM DUAL;

查询1

-- Negative Matches:
SELECT string
FROM   strings s
       LEFT OUTER JOIN
       patterns p
       ON ( REGEXP_LIKE( string, pattern ) )
WHERE  p.pattern IS NULL

<强> Results

|            STRING |
|-------------------|
| BM_HTCEVOBLKHS_BX |
| A_HTCEVODSAP_DSSD |
| A_HTCEVOB_A_CDSED |
| MP_HTCEVOBLKHS_BX |

查询2

-- Positive Matches:
SELECT DISTINCT
       string
FROM   strings s
       INNER JOIN
       patterns p
       ON ( REGEXP_LIKE( string, pattern ) )

<强> Results

|            STRING |
|-------------------|
| AM_HTCEVOBLKHS_BX |
| AP_HTCEVOBLKHSPBX |

查询3

-- All Matches:
SELECT string,
       CASE WHEN REGEXP_LIKE( string,
                              ( SELECT LISTAGG( pattern, '|' ) WITHIN GROUP ( ORDER BY NULL )
                                FROM   patterns )
                            )
            THEN 'True'
            ELSE 'False'
            END AS Matched
FROM   strings s

<强> Results

|            STRING | MATCHED |
|-------------------|---------|
| AM_HTCEVOBLKHS_BX |    True |
| AP_HTCEVOBLKHSPBX |    True |
| BM_HTCEVOBLKHS_BX |   False |
| A_HTCEVODSAP_DSSD |   False |
| A_HTCEVOB_A_CDSED |   False |
| MP_HTCEVOBLKHS_BX |   False |

如果您想将模式作为单个字符串传递,那么:

查询4

-- Negative Matches:
SELECT string
FROM   strings
WHERE  NOT REGEXP_LIKE( string, '^(AM|AP)' )

<强> Results

|            STRING |
|-------------------|
| BM_HTCEVOBLKHS_BX |
| A_HTCEVODSAP_DSSD |
| A_HTCEVOB_A_CDSED |
| MP_HTCEVOBLKHS_BX |

查询5

-- Positive Matches:
SELECT string
FROM   strings
WHERE  REGEXP_LIKE( string, '^(AM|AP)' )

<强> Results

|            STRING |
|-------------------|
| AM_HTCEVOBLKHS_BX |
| AP_HTCEVOBLKHSPBX |

查询6

-- All Matches:
SELECT string,
       CASE WHEN REGEXP_LIKE( string, '^(AM|AP)' )
            THEN 'True'
            ELSE 'False'
            END AS Matched
FROM   strings

<强> Results

|            STRING | MATCHED |
|-------------------|---------|
| AM_HTCEVOBLKHS_BX |    True |
| AP_HTCEVOBLKHSPBX |    True |
| BM_HTCEVOBLKHS_BX |   False |
| A_HTCEVODSAP_DSSD |   False |
| A_HTCEVOB_A_CDSED |   False |
| MP_HTCEVOBLKHS_BX |   False |

答案 2 :(得分:0)

试试这个:

^([B-Z][A-Z]*|A[A-LNOQ-Z]?|A[A-Z]{2,})_[A-Z_]+$

这个想法是描述字符串的所有可能的开始。

(                 # a group
    [B-Z][A-Z]*   # The first character is not a "A"
  |               # OR
    A[A-LNOQ-Z]?  # a single "A" or a "A" followed by a letter except "P" or "M"
  |               # OR
    A[A-Z]{2,}    # a "A" followed by more than 1 letter
)                 # close the group

^$是锚点,表示“字符串的开头”和“字符串的结尾”

答案 3 :(得分:0)

我认为你需要这个:

not regexp_like( field, '^(AM_)|^(AP_)' )

因为它是一个LIKE函数,所以你不需要再使用正则表达式。