2014-09-02 121 views
2

我遇到查詢問題。我使用mysql作爲數據庫。我想用一個正則表達式的結果我預期匹配,並且表是匹配MySQL中的正則表達式,包含條件的重複單詞不包括括號

table A 

---------------------------------- 
| ID | Description   | 
---------------------------------- 
| 1 | new 2 new 2 new 2 new | 
| 2 | new 21 new 2 new  | 
| 3 | new 2th 2 (2/2)  | 
| 4 | 2new 2new (2/2)  | 
| 5 | new2 new 2new  | 

我預計
結果 - 數字2只能說明兩次
- 字符2日前後/必須爲VARCHAR(除了後空白)
- 特殊條件:用圖案的任何數字 「(數字/數字)」 之類ID = 3和ID = 4是可接受


| ID | Description   | 
--------------------------------- 
| 3 | new 2th 2 (2/2)  | 
| 4 | 2new 2new (2/2)  | 
| 5 | new2 new 2new  | 

我試圖S上的查詢Ø遠

http://sqlfiddle.com/#!2/a227b/2

+0

對不起..錯誤的打字 – muhnizar 2014-09-02 02:32:15

+0

在第二個期望中,除了空格外,你的意思是什麼 – hwnd 2014-09-02 02:35:16

+0

- 它沒有在ID = 2中顯示結果,因爲在2之後有1(2之後的字符必須是varchar) - 它會在ID = 3中顯示結果,因爲之前/之前2只有空白(除了在空白之前/之前) – muhnizar 2014-09-02 02:39:56

回答

0

我提出這個表達式:

^([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])*([[:<:]]|[a-z])2([[:>:]]|[a-z])([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])+([[:<:]]|[a-z])2([[:>:]]|[a-z])([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])*$ 

這是一個有點長,但它允許在這些字符串一些更大的靈活性被認爲是 '有效',以及:

(2/2) 2new 2new 
2new (2/2) 2new (2/2) 

在代碼

SELECT 
    * 
FROM 
    A 
WHERE 
    description REGEXP '^(([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*2([[:>:]]|[a-z])){2}([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*$' 

SQLFiddle

正則表達式擊穿

實際使用許多重複的部分,所以這就是爲什麼它是一個有點長的正則表達式:

^          # Beginning of string 

(          # Open repeat group 
    ([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])* # Any characters. See #1 
    2          # 2 
    ([[:>:]]|[a-z])      # Word boundary or alphabet/letter. See #2 
){2}          # Close repeat group and repeat 2 times 

([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*  # Any characters. See #1 

$ 

明細表

  • #1

    (   # Open group 
    
        [^2]+  # Any characters except 2 
    
    |   # OR 
    
        [[:<:]] # Open word boundary 
        [0-9]+ # Any numbers 
    /  # Forward slash 
        [0-9]+ # Any numbers 
        [[:>:]] # Close word boundary 
    
    )*   # Close group and repeat any number of times 
    
  • #2

    (   # Open group 
        [[:>:]] # Word boundary 
    |   # Or 
        [a-z]  # Letter/alphabet 
    )   # Close group 
    

詞邊界開始和詞語的末端相匹配。這裏一個單詞的定義是一系列字母,數字和下劃線字符。

[[:<:]]是一個開頭的單詞邊界,因此匹配在單詞的開頭。

[[:>:]]是一個開頭的單詞邊界,因此匹配在單詞的末尾。這裏

它們的使用保證了2(和數字/數字的部分)不被其他數字(因此使得21失敗的例子)包圍或計數一個2如果你有例如21/4爲一體,其對朝兩個2 s在字符串中。

0

有可能是一種方法用一個正則表達式來做到這一點,但我覺得它更容易使用三:

select * 
from a 
where description regexp '[a-zA-Z ]+[0-9]+[a-zA-Z ]+[0-9]+' and 
     (description not regexp '[0-9]+[^0-9]+[0-9]+[^0-9]+[0-9]+' or 
     description regexp '[0-9]+[^0-9]+[0-9]+[^0-9]+[0-9]+/[0-9]+' 
    ); 

編輯:

我沒有實現目標只是爲了2而不是任何數字。這符合你的規則,但不是你的結果(4不屬於):

select * 
from a 
where description regexp '[a-zA-Z ]+[2]+[a-zA-Z ]+[2]+' and 
     (description not regexp '[2]+[^0-9]+[2]+[^0-9]+[2]+' or 
     description regexp '[2]+[^0-9]+[2]+[^0-9]+2/2' 
    ); 
+0

我仍然得到錯誤的結果 – muhnizar 2014-09-02 02:42:32

相關問題