Parse the trigger pattern
        :param element: The XML Element object
        :type  element: etree._Element

def _parse_pattern(self, element):
        """
        Parse the trigger pattern
        :param element: The XML Element object
        :type  element: etree._Element
        """
        # If this is a raw regular expression, compile it and immediately return
        self._log.info('Parsing Trigger Pattern: ' + element.text)
        self.pattern_words, self.pattern_len = self.count_words(element.text)
        self._log.debug('Pattern contains {wc} words with a total length of {cc}'
                        .format(wc=self.pattern_words, cc=self.pattern_len))

        regex = bool_attribute(self._element, 'regex', False)
        if regex:
            self._log.info('Attempting to compile trigger as a raw regex')
            try:
                self.pattern = re.compile(element.text)
            except sre_constants.error:
                self._log.warn('Attempted to compile an invalid regular expression in {path} ; {regex}'
                               .format(path=self.file_path, regex=element.text))
                raise AgentMLSyntaxError
            return

        self.pattern = normalize(element.text, True)
        self._log.debug('Normalizing pattern: ' + self.pattern)
        compile_as_regex = False

        # Wildcard patterns and replacements
        captured_wildcard = re.compile(r'(?<!\\)\(\*\)')
        wildcard = re.compile(r'(?<!\\)\*')

        capt_wild_numeric = re.compile(r'(?<!\\)\(#\)')
        wild_numeric = re.compile(r'(?<!\\)#')

        capt_wild_alpha = re.compile(r'(?<!\\)\(_\)')
        wild_alpha = re.compile(r'(?<!\\)_')

        wildcard_replacements = [
            (captured_wildcard, r'(.+)'),
            (wildcard,          r'(?:.+)'),
            (capt_wild_numeric, r'(\d+)'),
            (wild_numeric,      r'(?:\d+)'),
            (capt_wild_alpha,   r'([a-zA-Z]+)'),
            (wild_alpha,        r'(?:[a-zA-Z]+)'),
        ]

        for wildcard, replacement in wildcard_replacements:
            self.pattern, match = self.replace_wildcards(self.pattern, wildcard, replacement)
            compile_as_regex = bool(match) or compile_as_regex

        # Required and optional choices
        req_choice = re.compile(r'\(([\w\s\|]+)\)')
        opt_choice = re.compile(r'\s?\[([\w\s\|]+)\]\s?')

        if req_choice.search(self.pattern):
            def sub_required(pattern):
                patterns = pattern.group(1).split('|')
                return r'(\b{options})\b'.format(options='|'.join(patterns))

            self.pattern = req_choice.sub(sub_required, self.pattern)
            self._log.debug('Parsing Pattern required choices: ' + self.pattern)
            compile_as_regex = True

        if opt_choice.search(self.pattern):
            def sub_optional(pattern):
                patterns = pattern.group(1).split('|')
                return r'\s?(?:\b(?:{options})\b)?\s?'.format(options='|'.join(patterns))

            self.pattern = opt_choice.sub(sub_optional, self.pattern)
            self._log.debug('Parsing Pattern optional choices: ' + self.pattern)
            compile_as_regex = True

        if compile_as_regex:
            self._log.debug('Compiling Pattern as regex')
            self.pattern = re.compile('^{pattern}$'.format(pattern=self.pattern), re.IGNORECASE)
        else:
            self._log.debug('Pattern is atomic')
            self.pattern_is_atomic = True

            # Replace any escaped wildcard symbols
            self._log.debug('Replacing any escaped sequences in Pattern')
            self.pattern = self.pattern.replace('\*', '*')
            self.pattern = self.pattern.replace('\#', '#')
            self.pattern = self.pattern.replace('\_', '_')

            # TODO: This needs revisiting
            self.pattern = self.pattern.replace('\(*)', '(*)')
            self.pattern = self.pattern.replace('\(#)', '(#)')
            self.pattern = self.pattern.replace('\(_)', '(_)')