2017-03-16 193 views
1

我在postgres中制作一个复杂的模式匹配查询时遇到了一些问题,我想要一些建议。复杂的postgresql模式匹配

我有大约55k的登记与项目代码,他们必须具有下列规则图案的表:

  1. 必须以字母开头CNF
  2. 必须有以下的空间“ CNF”字母
  3. 的空间后而来的,是数序列必须始终是8号
  4. 在此之后第一个序列来自另一个空间
  5. 第二空间来自另一个SE后可以有任何数量的数字。

下面是一些例子:

"CNF 56500155 99" 
"CNF 51100039 3666" 
"CNF 51100090 0985" 
"CNF 52300021 07" 
"CNF 52300020 4602" 
"CNF 56700091 2515" 
"CNF 56700091 387" 
"CNF 56700091 4784" 
"CNF 56500155 2066" 
"CNF 56900149 6266" 
"CNF 56300009 175" 
"CNF 56700091 4782" 
"CNF 51100084 2445" 
"CNF 51100062 2379" 
"CNF 52900014 0920" 
"CNF 51100077 707" 
"CNF 51100077 9706" 
"CNF 51100101 6580" 
"CNF 51500014 8929" 
"CNF 56700091 79" 
"CNF 51100090 8510" 
"CNF 51100090 8508" 
"CNF 51100090 8506" 
"CNF 56700091 4774" 
"CNF 51100101 9879" 
"CNF 51100077 696" 
"CNF 51100004 5083" 
"CNF 56700091 4773" 
"CNF 56500155 8616" 
"CNF 51100039 324523423" 
"CNF 51100090 5786" 
"CNF 56700091 771" 
"CNF 51100077 9692" 
"CNF 51100077 9691" 
"CNF 51500014 18928" 
"CNF 56700091 24770" 
"CNF 51100077 9685" 

我想打一个模式匹配查询来获取它可以有以下的问题,而不是期望的模式的所有登记。

"CNF56500155 99" <-- No space between CNF and first sequence 
    "CNF 51100039 3666" <-- Double or more spaces between CNF and first sequence 
    "CNF 511000900985" <-- No space between first and second sequences 
    "CNF 52300021  07" <-- Double or more spaces between first and second sequences 
    "CNF 523000 07" <-- Less that eight numbers on the first sequence 

我试着用括号内通配符和人物不同querys,但似乎无法找到正确的一个,任何人都可以帮助我吗?

回答

1

的代码应与正则表达式模式^CNF \d{8} \d+$,所以你应该选择不匹配此模式的所有行,例如:

with codes(code) as (
values 
    ('CNF 51100077 9692'), 
    ('CNF 51100077 9691'), 
    ('CNF 51500014 18928'), 
    ('CNF 56700091 24770'), 
    ('CNF 51100077 9685'), 
    ('CNF56500155 99'), 
    ('CNF 51100039 3666'), 
    ('CNF 511000900985'), 
    ('CNF 52300021  07'), 
    ('CNF 523000 07') 
) 

select code 
from codes 
where code !~ '^CNF \d{8} \d+$'; 

     code   
--------------------- 
CNF56500155 99 
CNF 51100039 3666 
CNF 511000900985 
CNF 52300021  07 
CNF 523000 07 
(5 rows)  

Read about pattern matching with regular expressions.


附录。您可以在表上使用检查约束来防止插入与模式不一致的数据,例如

create table my_table (
    id int primary key, 
    code text 
); 

-- note that you can add this check constraint 
-- only if there are no rows which violate the condition 
alter table my_table add check (code ~ '^CNF \d{8} \d+$'); 

insert into my_table 
values (1, 'CNF 523000 07'); 

ERROR: new row for relation "my_table" violates check constraint "my_table_code_check" 
DETAIL: Failing row contains (1, CNF 523000 07). 
+0

这正是我一直在寻找的。非常感谢你。 :d – Omaruchan