3

我有一个正则表达式,可以来自:

(src://path/to/foldernames canhave spaces/file.xzy)
(src://path/to/foldernames canhave spaces/file.xzy "optional string")

这些表达式出现在更长的字符串中(它们不是单独的字符串)。re.search使用or时我无法匹配这两个表达式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'

While匹配第一个组,但在第二个实例\((.*)( ".*")?\)中没有单独将其标识为一个组。"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)

有什么想法,你们的表达大师(常规品种)?

4

2 回答 2

4

最简单的方法是使第一个* 非贪婪

>>> 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', '')]
于 2013-08-24T15:50:13.770 回答
2

由于"通常不允许出现在文件名中,您可以简单地将它们从第一组中排除:

r = re.search(r'\(([^"]*)( ".*")?\)', input)

这通常是不贪婪重复的首选替代方法,因为它往往效率更高。如果您的文件名由于某种原因实际上可以包含引号,那么不贪婪的重复(如 agf 的答案)是您最好的选择。

于 2013-08-24T16:10:40.413 回答