2015-10-22 24 views
0

目標:返回分組匹配所有開始序列但排除大小序列。Python - 正則表達式 - 匹配所有開始序列排除其他模式

## List of strings and desired result 
strs = [ 
    '151002 - Some name',  ## ('151002 - ', 'Some name') 
    'Another name here',  ## ('', 'Another name here') 
    '13-10-07_300x250_NoName', ## ('13-10-07_', '300x250_NoName') 
    '728x90 - nice name'  ## ('', '728x90 - nice name') 
] 

嘗試模式

## This pattern is close 
## 
pat = ''' 
^      ## From start of string 
(      ## Group 1 
    [0-9\- ._/]*   ## Any number or divider 
    (?!     ## Negative Lookahead 
     (?:\b|[\- ._/\|]) ## Beginning of word or divider 
     \d{1,3}   ## Size start 
     (?:x|X)   ## big or small 'x' 
     \d{1,3}   ## Size end 
    )   
) 
(      ## Group 2 
    .*     ## Everthing else 
) 
''' 

## Matching 
[re.compile(pat, re.VERBOSE).match(s).groups() for s in strs] 

嘗試的模式結果

[ 
    ('151002 - ', 'Some name'),  ## Good 
    ('', 'Another name here'),  ## Good 
    ('13-10-07_300', 'x250_NoName'), ## Error 
    ('728', 'x90 - nice name')  ## Error 
] 

回答

1

我想你誤會了使用lookaheads。這種模式應該工作

((?:(?!\d{1,3}x\d{1,3})[0-9\- ._/])*)(.*) 

Regular expression visualization

Debuggex Demo

如果你想要一個解釋,因爲我知道這是一個噁心的正則表達式,只要求輸入:)

+0

哇! @ r-nar多麼神奇的工具!非常感謝你的分享!我仍然沒有得到如何使用前瞻性的例子和工具讓我更接近。 **:)**看起來像我在網上遇到的每個示例都使用lookahead作爲**不包含**(因此在我的示例中,如果任何字符串具有大小 - 即300x250),則該模式將失敗)。所以當然遵循並修改它們的邏輯,我把前瞻視爲**期望的**模式的​​前面。你有什麼好的前瞻參考? – propjk007

+0

我真的沒有很好的參考,但如果有幫助,可以將前瞻/後視報表視爲探針。每當正則表達式到達一個時,它將保持它的當前位置,同時使用'另一個'標記在字符串之前或之後,並匹配先行語句中的任何內容。 –

+0

也,我使用rexegg.com我的任何正則表達式的問題,它是一個很好的概述正則表達式和技巧的網站,並提示如何使用它 –

3

我想,這可能會給你想要的東西:

[re.match(r"^([^x]+[\-_]\s?)?(.*$)", s).groups() for s in strs] 

正則表達式的解釋:從字符串的開頭開始,查找一個或多個不是x的字符,後面跟一個連字符或下劃線,可能後跟一個空格。這是第一組,可以有零個或一個。第二組就是一切。

編輯:

假設你的字符串可以有比X字母數字除其他東西,你可以修改代碼以這樣的:

[re.match(r"^([^a-zA-Z]+[\-_]\s?)?(.*$)", s).groups() for s in strs] 
+0

的感謝!雖然這個正則表達式似乎並不符合我在尋找的內容(請參閱[這裏](https://regex101.com/r/cG8cT5/1)),但您的方法確實提醒我,有多種方法可以解決此問題。你的方法是更全面的,而我正在努力做到非常精確。我可以看到這種風格的好處。感謝您的文章! – propjk007

+0

@ propjk007根據您在評論中提供的鏈接,我假設連字符後面的額外空間導致了糟糕的輸出,是嗎?如果是這樣,我們可以通過移動第一個捕獲組之外的空間來解決這個問題,就像這樣:'[re.match(r「^([^ a-zA-Z] + [\ -_])?\ s? (。* $)「,s).groups()for s in strs]',這給了我們所需的輸出。你說得對,有多種方法可以解決同一個問題,特別是涉及到正則表達式時。我很高興你能找到解決問題的辦法。 – brittenb