If you don't mind the extra weight in the case where both prefix "A" and suffix "B" exist, you can use a shorter regex:
reMatcher= re.compile(r"(?<=\AA).*|.*(?=B\Z)")
(using \A
for ^
and \Z
for $
)
This one keeps the "A" prefix (instead of the "B" prefix of your solution) when both "A" and "B" are at their respective corners:
'A text here' matches ' text here'
'more text hereB' matches 'more text here'
'AYES!B' matched 'AYES!'
'neither' doesn't match
Otherwise, a non-regex solution (some would say a more “Pythonic” one) is:
def strip_prefix_suffix(text, prefix, suffix):
left = len(prefix) if text.startswith(prefix) else 0
right= -len(suffix) if text.endswith(suffix) else None
return text[left:right] if left or right else None
If there is no match, the function returns None
to differentiate from a possible ''
(e.g. when called as strip_prefix_suffix('AB', 'A', 'B')
).
PS I should also say that this regex:
(?<=\AA).*(?=B\Z)|(?<=\AA).*|.*(?=B\Z)
should work, but it doesn't; it works just like the one I suggested, and I can't understand why. Breaking down the regex into parts, we can see something weird:
>>> text= 'AYES!B'
>>> re.compile('(?<=\\AA).*(?=B\\Z)').search(text).group(0)
'YES!'
>>> re.compile('(?<=\\AA).*').search(text).group(0)
'YES!B'
>>> re.compile('.*(?=B\\Z)').search(text).group(0)
'AYES!'
>>> re.compile('(?<=\\AA).*(?=B\\Z)|(?<=\\AA).*').search(text).group(0)
'YES!'
>>> re.compile('(?<=\\AA).*(?=B\\Z)|.*(?=B\\Z)').search(text).group(0)
'AYES!'
>>> re.compile('(?<=\\AA).*|.*(?=B\\Z)').search(text).group(0)
'AYES!'
>>> re.compile('(?<=\\AA).*(?=B\\Z)|(?<=\\AA).*|.*(?=B\\Z)').search(text).group(0)
'AYES!'
For some strange reason, the .*(?=B\\Z)
subexpression takes precedence, even though it's the last alternative.