If the quoted sub-strings to be matched do NOT contain escaped characters, then both Karl Barker's and Pierce's answers will both match correctly. However, of the two, Pierce's expression is more efficient:
reobj = re.compile(r"""
# Match double quoted substring (no escaped chars).
" # Match opening quote.
( # $1: Quoted substring contents.
[^"]* # Zero or more non-".
) # End $1: Quoted substring contents.
" # Match closing quote.
""", re.VERBOSE)
But if the quoted sub-string to be matched DOES contain escaped characters, (e.g. "She said: \"Hi\" to me.\n"), then you'll need a different expression:
reobj = re.compile(r"""
# Match double quoted substring (allow escaped chars).
" # Match opening quote.
( # $1: Quoted substring contents.
[^"\\]* # {normal} Zero or more non-", non-\.
(?: # Begin {(special normal*)*} construct.
\\. # {special} Escaped anything.
[^"\\]* # more {normal} Zero or more non-", non-\.
)* # End {(special normal*)*} construct.
) # End $1: Quoted substring contents.
" # Match closing quote.
""", re.DOTALL | re.VERBOSE)
There are several expressions I'm aware of that will do the trick, but the one above (taken from MRE3) is the most efficient of the bunch. See my answer to a similar question where these various, functionally identical expressions are compared.