正则表达式:带可选部分的字符串

Bio*_*eek 8 python regex

我试图解析一些docstrings.

一个示例文档字符串是:

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
Run Code Online (Sandbox Code Playgroud)

无论是ArgumentsReturns部分都是可选的.我希望我的正则表达式以组的形式返回描述(第一行),Arguments部分(如果存在)和Returns部分(如果存在).

我现在的正则表达式是:

m = re.search('(.*)(Arguments:.*)(Returns:.*)', s, re.DOTALL)
Run Code Online (Sandbox Code Playgroud)

如果所有三个部件都存在但是一旦失败ArgumentsReturns部件不可用则起作用.我曾尝试使用非贪婪修饰符的几种变体,??但无济于事.

编辑:ArgumentsReturns部分存在时,我实际上只想分别匹配文本Arguments:Returns:.

谢谢!

Che*_*wie 9

试试:

re.search('^(.*?)(Arguments:.*?)?(Returns:.*)?$', s, re.DOTALL)
Run Code Online (Sandbox Code Playgroud)

只需通过附加a 使第二组和第三组成为可选项?,并使前两组的限定符非贪婪(再次)附加一个?(是的,令人困惑).

此外,如果在模式的第一组上使用非贪婪修饰符,它将匹配最短的子字符串,其中for .*为空字符串.您可以通过在模式的末尾添加行尾字符($)来克服这个问题,这会强制第一个组匹配尽可能少的字符以满足模式,即当没有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'
>>>
Run Code Online (Sandbox Code Playgroud)


Pyt*_*Jin 5

如果您想匹配 optionalArguments:Returns:部分之后的文本,并且您不想使用(?P<name>...)来命名您的捕获组,您还可以使用, (?:...),常规括号的非捕获版本。

正则表达式如下所示:

m = re.search('^(.*?)(?:Arguments:(.*?))?(?:Returns:(.*?))?$', doc, re.DOTALL)
#                     ^^                  ^^
Run Code Online (Sandbox Code Playgroud)

根据 Python3文档

(?:...)

常规括号的非捕获版本。匹配括号内的任何正则表达式,但在执行匹配或稍后在模式中引用后,无法检索与组匹配的子字符串。