def METHOD_NAME(self, text):
    whitespace = partial(re.sub, r"\s{1,4}", r"\\s{,4}")
    # Run the before hook.
    text = self.before_categorize(text)
    for func in self._before_funcs:
        text = func(text)
    types = set()
    attrs = defaultdict(set)
    for rule in self.rules:
        for regex in rule.regexes:
            # Try to match the regex.
            m = re.search(whitespace(regex), text)
            if m or (regex in text):
                # If so, apply its associated types to this action.
                types |= rule.types
                # Also add its specified attrs.
                for k, v in m.groupdict().items():
                    attrs[k].add(v)
                for k, v in rule.attrs.items():
                    attrs[k].add(v)
                # Break if the rule says so, otherwise
                # continue testing against other rules.
                if rule.stop is True:
                    break
    # Returns types, attrs
    return_val = (list(types), attrs)
    return_val = self.after_categorize(return_val)
    for func in self._after_funcs:
        return_val = func(*return_val)
    return self.finalize(return_val)