我正在尝试解析一些文档字符串。
示例文档字符串是:
Test if a column field is larger than a given value
This function can also be called as an operator using the '>' syntax
Arguments:
- DbColumn self
- string or float value: the value to compare to
in case of string: lexicographic comparison
in case of float: numeric comparison
Returns:
DbWhere object
Arguments
和Returns
部分都是可选的。我希望我的正则表达式以组的形式返回描述(第一行),Arguments
部分(如果存在)和Returns
部分(如果存在)。
我现在的正则表达式是:
m = re.search('(.*)(Arguments:.*)(Returns:.*)', s, re.DOTALL)
并在以下所有三个部分都存在的情况下工作,但只要Arguments
或Returns
部分不可用就会失败。我已尝试使用非贪婪修饰符(如??
)进行多种修改,但无济于事。
修改:当Arguments
和Returns
部分存在时,我实际上只想匹配Arguments:
和Returns:
之后的文字分别
谢谢!
答案 0 :(得分:9)
尝试:
re.search('^(.*?)(Arguments:.*?)?(Returns:.*)?$', s, re.DOTALL)
只需通过附加?
制作第二组和第三组可选,并通过(再次)制作前两组非贪婪的限定符在?
上添加.*
(是的,令人困惑)。
此外,如果在模式的第一组上使用非贪婪修饰符,它将匹配最短的子字符串,$
为空字符串。您可以通过在模式的末尾添加行尾字符(Arguments
)来克服这个问题,这会强制第一个组匹配尽可能少的字符以满足模式,即整个字符串何时出现没有Returns
和没有Arguments:
部分,以及这些部分之前的所有部分(如果存在)。
编辑:好的,如果您只想在 Returns:
和<?P<name>
令牌之后捕获文本,那么您将不得不掖好在几个小组中。我们不打算使用所有组,因此用>>> m = re.search('^(?P<description>.*?)(Arguments:(?P<arguments>.*?))?(Returns:(?P<returns>.*))?$', s, re.DOTALL)
>>> m.groupdict()['description']
"Test if a column field is larger than a given value\n This function can also be called as an operator using the '>' syntax\n\n "
>>> m.groupdict()['arguments']
'\n - DbColumn self\n - string or float value: the value to compare to\n in case of string: lexicographic comparison\n in case of float: numeric comparison\n '
>>> m.groupdict()['returns']
'\n DbWhere object'
>>>
符号(另一个问号,argh!)命名它们 - 开始有意义了:
{{1}}
答案 1 :(得分:3)
如果您想在可选的Arguments:
和Returns:
部分 AND 之后匹配文字,则不希望使用(?P<name>...)
命名您的捕获组,您也可以使用(?:...)
非常规括号的捕获版本。
正则表达式看起来像这样:
m = re.search('^(.*?)(?:Arguments:(.*?))?(?:Returns:(.*?))?$', doc, re.DOTALL)
# ^^ ^^
根据Python3 documentation:
(?:...)
常规括号的非捕获版本。匹配括号内的正则表达式,但在执行匹配后或在模式中稍后引用时,无法检索组匹配的子字符串。