我有一个正则表达式,可以来自:
(src://path/to/foldernames canhave spaces/file.xzy)
(src://path/to/foldernames canhave spaces/file.xzy "optional string")
这些表达式出现在一个更长的字符串中(它们不是单独的字符串)。在使用re.search
或re.findall
时,我无法匹配两个表达式(因为字符串中可能有多个表达式)。
它足够简单,可以单独匹配,但如何匹配任何一种情况,以便返回两个组,第一组返回src://path/...
,第二组返回optional string
存在或None
如果不存在?
我在想我需要以某种方式指定OR组 - 例如,考虑:
模式\((.*)( ".*")\)
匹配第二个实例,但不匹配第一个实例,因为它不包含"..."
。
r = re.search(r'\((.*)( ".*")\)', '(src://path/to/foldernames canhave spaces/file.xzy)'
r.groups() # Nothing found
AttributeError: 'NoneType' object has no attribute 'groups'
虽然\((.*)( ".*")?\)
与第一个组匹配,但在第二个实例中没有单独将"optional string"
标识为一个组。
r = re.search(r'\((.*)( ".*")?\)', '(src://path/to/foldernames canhave spaces/file.xzy "optional string")')
r.groups()
('src://path/to/foldernames canhave spaces/file.xzy "optional string"', None)
任何想法,你们'表达的主人(常规品种)?
答案 0 :(得分:4)
最简单的方法是制作第一个*
non-greedy:
>>> import re
>>> string = "(src://path/to/foldernames canhave spaces/file.xzy)"
>>> string2 = \
... '(src://path/to/foldernames canhave spaces/file.xzy "optional string")'
>>> re.findall(r'\((.*?)( ".*")?\)', string2)
[('src://path/to/foldernames canhave spaces/file.xzy', ' "optional string"')]
>>> re.findall(r'\((.*?)( ".*")?\)', string)
[('src://path/to/foldernames canhave spaces/file.xzy', '')]
答案 1 :(得分:2)
由于"
通常不允许出现在文件名中,因此您只需将其从第一组中排除即可:
r = re.search(r'\(([^"]*)( ".*")?\)', input)
这通常是the preferred alternative to ungreedy repetition,因为往往效率更高。如果您的文件名由于某种原因实际上可以包含引号,那么不合理的重复(如agf的答案中)是您最好的选择。