Cemu
Cemu

Reputation: 51

regex don't match docstring if commented

I want to match this (including whitespace) from:

def foo():
    """
    this
    """

    pass

but in this case i don't want to match anything:

# def foo():
#    """
#    this
#    """
#  
#    pass

At the moment I am using """(.*?)""" with the DOTALL-flag to catch the first example, but obviously that doesn't prevent the matching of the second part. This regex doesn't work because it prevents any matches after the first occurance of #: ^(?!#)"""(.*?)"""

Upvotes: 0

Views: 219

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627083

Use a common work-around: match what you do not need and match and capture what you need:

(?sm)^#[^\r\n]*|"""(.*?)"""

See the regex demo. Only collect Group 1 values.

Details

  • (?sm) - re.MULTILINE and re.DOTALL flags
  • ^ - start of a line
  • # - a # char
  • [^\r\n]* - the rest of the line (0+ chars other than CR and LF)
  • | - or
  • """ - a """ string
  • (.*?) - Group 1: zero or more chars as few as possible
  • """ - a """ string

Example Python 3 code:

import re
rx = r'^#[^\r\n]*|"""(.*?)"""'
s = "def foo():\n    \"\"\"\n    this\n    here\n    \"\"\"\n\n    pass\n\n\n# def foo():\n#    \"\"\"\n#    this\n#    here\n#    \"\"\"\n#  \n#    pass"
res = re.findall(rx, s, re.DOTALL|re.MULTILINE)
print(list(filter(None, res)))
# => ['\n    this\n    here\n    ']

Upvotes: 1

Related Questions