2012-06-20 65 views
0

我有一個字符串,它看起來像這樣:在Python正則表達式中,如何忽略捕獲組中的表達式?

<name>-<gender>-<age>.jpg 

我想是非常自由的,只要我接受。要求爲:

  1. <name>組件是必需的。
  2. 必須有.jpg文件擴展
  3. ,則可以留一個組件空白或離開它,只要完全是作爲最終的結果是下面的排列之一:
    • <name>.jpg
    • <name>-<gender>.jpg
    • <name>-<gender>-<age>.jpg

舉例什麼被認爲是有效的:

Beamin-M.jpg 
Jean.jpg 
Maria-F-23.jpg 

我想打破使用正則表達式字符串的每個組成部分,但我不想要捕捉的破折號(-)。我嘗試使用非捕獲組,但沒能得到我想要的結果:

>>> import re 
>>> r = re.compile(r'([^\-]*)((?:\-)[^\-]*)?((?:\-)[^\-]*)?\.jpg') 
>>> for d in (
... 'Beamin-M.jpg', 
... 'Jean.jpg', 
... 'Maria-F-23.jpg', 
...): 
... print r.match(d).groups() 
... 
('Beamin', '-M', None) 
('Jean', None, None) 
('Maria', '-F', '-23') 

有沒有人有什麼建議?

回答

6

我不是正則表達式的一個巨大的風扇時,有現成的更邏輯友好的解決方案,所以我想嘗試這樣的事:

from os.path import splitext  

test = '<name>-<gender>-<age>.jpg' 

fname, ext = splitext(test) # works with names like 'xxx.yyy.jpg' 
if ext in ('.jpg', '.jpeg'): 
    name, gender, age = (fname.split('-') + [None, None])[:3] 
+0

我同意。編寫正則表達式時可能會犯錯,直到很晚纔會意識到它。正則表達式需要大量正面和負面的單元測試來確保一切正確。我投票給你指出這一點。 – varunl

+0

很好的答案。什麼時候不回答確切問題的完美例子值得綠色檢查。 –

2

重寫你的正則表達式爲:

r'([^\-]*)(?:-([^\-]*))?(?:-([^\-]*))?\.jpg' 

從技術上講,你不需要在字符類[]逃脫-,因爲它是最後的類。但我只是把它放在安全的一邊。

+0

你可能要替換'*'和'+ ',否則它匹配'瑪麗亞 - 23' – georg

+0

@ thg435:我只修復OP的嘗試。由於他對這些案件沒有提出任何意見,我認爲除了額外的短劃線「-'外,他對結果感到滿意。 – nhahtdh

0

咦?

你的意思R '([^ - ] )(:(: - ?)([^ - ]))((?: - )[^ - ] *)?JPG')

嚴重的是,你捕捉的破折號,因爲它是在外部捕獲括號。