Customizable code for easy changes and future demands.
2 Different attitudes.
You can subclass it, change regex parser, act functions and etc..
import re
class Executor:
def __init__(self, action_dict):
self.action_dict = action_dict
self.keys = list(action_dict.keys())
def regex_parser(self, regex):
return regex
def string_parser(self, string):
return string.lower()
def match(self, string):
for key in self.keys:
regex = re.compile(self.regex_parser(key))
if regex.search(self.string_parser(string)) is not None:
return self.act(key, string)
return None
def act(self, key, string):
func = self.action_dict[key]
return func(string)
executor = Executor(
{
"test": print,
"some": lambda s: print(s + " Hello matcher"),
"end$": lambda s: print("End"),
}
)
executor.match("testing")
executor.match("something")
executor.match("LegenD")
>>> testing
>>> something Hello matcher
>>> End
Second attitude is more verbose, but benefit is that each Matcher class can have its own set of rules and evaluation.
import re
class DefaultMatcher:
regex = "default"
def regex_parser(self, regex):
return regex
def string_parser(self, string):
return string.lower()
def function(self, string, *args, **kwargs):
"""This function is the action."""
return args, kwargs
def match(self, string, *args, **kwargs):
# Returns something or None
return self.compiled_regex.search(self.string_parser(string))
def __init__(self, *args, **kwargs):
self.compiled_regex = re.compile(self.regex_parser(self.regex))
def __call__(self, string, *args, **kwargs):
parsed_string = self.string_parser(string)
if self.match(string):
return self.function(string, *args, **kwargs)
else:
return None
class Matcher1(DefaultMatcher):
regex = "test1"
def function(self, *args, **kwargs):
return "Matcher_1"
class Matcher2(DefaultMatcher):
regex = "test2"
def function(self, *args, **kwargs):
return "Matcher_2"
class Matcher3(DefaultMatcher):
regex = "o"
def regex_parser(self, regex):
super_regex = super().regex_parser(regex)
return super_regex + "$"
def function(self, *args, **kwargs):
return "Matcher_3"
class DefaultExecutor:
def __init__(self, list_of_matcher, *args, **kwargs):
self.list_of_matcher = [matcher(*args, **kwargs) for matcher in list_of_matcher]
def __call__(self, string, *args, **kwargs):
for matcher in self.list_of_matcher:
result = matcher(string, *args, **kwargs)
if result is not None:
return result
executor = DefaultExecutor([Matcher1, Matcher2, Matcher3])
print(executor("test1"))
print(executor("Otto"))
print(executor("test2"))