2017-03-16 81 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