2012-06-20 61 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')

严重的是,你捕捉的破折号,因为它是在外部捕获括号。