简体   繁体   English

Oracle SQL 中的模式匹配

[英]Pattern Matching in Oracle SQL

I am trying to match some patterns and exclude some based on certain characters and lengths.我正在尝试匹配一些模式并根据某些字符和长度排除一些模式。

I want to return all 3 characters and 4 characters values:我想返回所有 3 个字符和 4 个字符的值:

  • The 3 character values should have any letter at 3rd position ie 11A 3 个字符值应该在第 3 个位置有任何字母,即11A
  • The 4 character values should have 2 letters at the end ie 11AB , but shouldn't have letters EF ie need to exclude values like 11EF . 4 个字符值的末尾应该有 2 个字母,即11AB ,但不应有字母EF即需要排除11EF值。

Table:桌子:

+------+
| CODE |
+------+
|   11 |
|  11A |
|  11B |
| 11EF |
| 11AB |
+------+

EXPECTED OUTPUT:预期产出:

+-----------------+
| EXPECTED OUTPUT |
+-----------------+
|             11A |
|             11B |
|            11AB |
+-----------------+

I've tried this but it returns all regardless of the conditions I mentioned above:我试过这个,但不管我上面提到的条件如何,它都会返回所有:

select REGEXP_SUBSTR('11EF','^[0-9]{1,2}[A-Z]{1,2}?')  from dual;

select REGEXP_SUBSTR('11','^[0-9]{1,2}[A-Z]{1,2}?')  from dual;

select REGEXP_SUBSTR('11A','^[0-9]{1,2}[A-Z]{1,2}?')  from dual;

This worked for me on Oracle Live SQL:这在 Oracle Live SQL 上对我有用:

create table temp( text varchar2(25));

INSERT INTO temp values ('11');
INSERT INTO temp values ('11A');
INSERT INTO temp values ('11B');
INSERT INTO temp values ('11EF');
INSERT INTO temp values ('11AB');
INSERT INTO temp values ('21ASDF');
INSERT INTO temp values ('31ASD');
INSERT INTO temp values ('251ASDF');
INSERT INTO temp values ('41ASDFDSF');

select text
from temp
where length(text) between 3 and 4
and (regexp_instr(text, '[[:alpha:]]', 3) > 0 or regexp_instr(text, '[[:alpha:]][[:alpha:]]', 3) > 0)
and substr(text, 3, 2) <> 'EF';

TEXT
11A
11B
11AB

I changed your regular-expression to this.我把你的正则表达式改成了这个。 It does not perform the EF -check in the regex but elsewhere in the query as that would make the regex far more complicated:它不会在正则表达式中执行EF -check,而是在查询的其他地方执行,因为这会使正则表达式变得更加复杂:

^(\d\d[A-Z])|(\d\d[A-Z]{2})$

And this query works for me in SqlFiddle.com :这个查询在 SqlFiddle.com 中对我有用

SELECT
  text_col
FROM
  Foo
WHERE
  REGEXP_INSTR( text_col, '^(\d\d[A-Z])|(\d\d[A-Z]{2})$' ) > 0
  AND
  REGEXP_INSTR( text_col, 'EF$' ) = 0

This uses a case-insensitive REGEXP_LIKE() that matches a string consisting of 2 characters followed by a letter OR 2 characters followed any letter except E, followed by any letter except F.这使用不区分大小写的 REGEXP_LIKE() 匹配由 2 个字符后跟一个字母或 2 个字符后跟除 E 之外的任何字母,后跟除 F 之外的任何字母组成的字符串。

with tbl(code) as (
  select '11' from dual union all
  select '11A' from dual union all
  select '11b' from dual union all
  select '11EF' from dual union all
  select '11FE' from dual union all
  select '11A#' from dual union all
  select '11BA' from dual union all
  select '1ZZZ' from dual union all  
  select NULL from dual union all
  select 'HELLO' from dual union all
  select 'A12' from dual
)
select code
from tbl
where regexp_like(code, '^((.{2}[A-Z])|(.{2}[A-D,F-Z][A-E,G-Z]))$', 'i');



CODE 
-----
11A  
11b  
11FE 
11BA 
1ZZZ 

5 rows selected.

EDIT: could be simplified a little to:编辑:可以简化为:

'^.{2}(([AZ])|([AD,FZ][AE,GZ]))$'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM