diff options
Diffstat (limited to 'cmd2/parsing.py')
-rw-r--r-- | cmd2/parsing.py | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/cmd2/parsing.py b/cmd2/parsing.py index f2c86ea8..a1e21175 100644 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -144,12 +144,26 @@ class StatementParser: # aliases have to be a word, so make a regular expression # that matches the first word in the line. This regex has two # parts, the first parenthesis enclosed group matches one - # or more non-whitespace characters (which may be preceeded - # by whitespace) and the second group matches either a whitespace - # character or the end of the string. We use \A and \Z to ensure - # we always match the beginning and end of a string that may have - # multiple lines - self.command_pattern = re.compile(r'\A\s*(\S+)(\s|\Z)+') + # or more non-whitespace characters with a non-greedy match + # (that's what the '+?' part does). The second group must be + # dynamically created because it needs to match either whitespace, + # something in REDIRECTION_CHARS, one of the terminators, + # or the end of the string. We use \A and \Z to ensure we always + # match the beginning and end of a string that may have multiple + # lines (if it's a multiline command) + second_group_items = [] + second_group_items.extend(constants.REDIRECTION_CHARS) + second_group_items.extend(terminators) + # escape each item so it will for sure get treated as a literal + second_group_items = [re.escape(x) for x in second_group_items] + # add the whitespace and end of string, not escaped because they + # are not literals + second_group_items.extend([r'\s', r'\Z']) + # join them up with a pipe + second_group = '|'.join(second_group_items) + # build the regular expression + expr = r'\A(\S+?)({})'.format(second_group) + self.command_pattern = re.compile(expr) def tokenize(self, line: str) -> List[str]: """Lex a string into a list of tokens. |