Skip to content

Instantly share code, notes, and snippets.

@luis261
Last active March 11, 2024 09:10
Show Gist options
  • Save luis261/f88a7c148a16b8f18448f9590eaa6422 to your computer and use it in GitHub Desktop.
Save luis261/f88a7c148a16b8f18448f9590eaa6422 to your computer and use it in GitHub Desktop.
def extract_between(src: str, start_delim: str, end_delim=None, fallback=None) -> str:
if end_delim is not None and src.count(start_delim) != src.count(end_delim):
raise ValueError("Unbalanced delimiters detected: \"" + src + "\"")
if src.count(start_delim) > 2 or src.count(start_delim) > 1 and (start_delim != end_delim):
raise ValueError("Duplicate delimiters detected: \"" + src + "\"")
delimit_front = lambda x : x[x.index(start_delim)+1:]
try:
if end_delim is None:
return delimit_front(src)
src = src[:(src[::-1].index(end_delim) + 1) * -1]
except ValueError: # could not find expected delimiter
if fallback is TypeError:
raise ValueError("This error class is not a valid fallback")
try:
issubclass(fallback, Exception)
except TypeError:
return fallback
else:
if issubclass(fallback, Exception):
raise fallback("The given string does not contain expected delimiters: \"" + src + "\"")
else:
raise TypeError("If your fallback is a class to be raised, please inherit from <Exception>")
else:
try:
return delimit_front(src)
except ValueError:
raise ValueError("Invalid delimiter positioning")
def _expect_err(fn, args, kwargs, err):
try:
fn(*args, **kwargs)
except Exception as e:
if isinstance(e, err):
return
raise TypeError("Expected " + str(type(err)) + ", but got " + str(type(e)))
raise AssertionError("Code under test did not raise the expected exception!")
''' rudimentary set of tests '''
def _test():
assert extract_between("a.bc", ".") == "bc" # base case, trailing
assert extract_between("[abc]", "[", end_delim="]") == "abc" # base case
assert extract_between("yz[abc]x", "[", end_delim="]") == "abc" # with padding
assert extract_between("yz.abc.x", ".", end_delim=".") == "abc" # identical delims
assert extract_between("abc", "[", end_delim="]") is None # nothing to extract
_expect_err(extract_between, ["]ab[c", "["], {"end_delim": "]"}, ValueError) # wrong order
_expect_err(extract_between, ["[a[bc]", "["], {"end_delim": "]"}, ValueError) # unbalanced
_expect_err(extract_between, ["[a[b]c]", "["], {"end_delim": "]"}, ValueError) # duplicates
_expect_err(extract_between, ["a.b..c", "."], {"end_delim": "."}, ValueError) # duplicates
_expect_err(extract_between, ["abc", "."], {"end_delim": ".", "fallback": TypeError}, ValueError) # invalid fallback, type
assert extract_between("abc", "[", end_delim="]", fallback="empty") == "empty" # valid fallback, instance (string)
_expect_err(extract_between, ["abc", "."], {"end_delim": ".", "fallback": Exception}, Exception) # valid fallback, type (Exception)
_expect_err(extract_between, ["abc", "."], {"end_delim" : ".", "fallback": int}, TypeError) # invalid fallback, type
if __name__ == "__main__":
_test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment