Convert, or unformat, a string to variables (like format(), but in reverse) in Python

前端 未结 7 2341
[愿得一人]
[愿得一人] 2020-12-15 03:44

I have strings of the form Version 1.4.0\\n and Version 1.15.6\\n, and I\'d like a simple way of extracting the three numbers from them. I know I

7条回答
  •  一生所求
    2020-12-15 04:00

    Here's a solution in case you don't want to use the parse module. It converts format strings into regular expressions with named groups. It makes a few assumptions (described in the docstring) that were okay in my case, but may not be okay in yours.

    def match_format_string(format_str, s):
        """Match s against the given format string, return dict of matches.
    
        We assume all of the arguments in format string are named keyword arguments (i.e. no {} or
        {:0.2f}). We also assume that all chars are allowed in each keyword argument, so separators
        need to be present which aren't present in the keyword arguments (i.e. '{one}{two}' won't work
        reliably as a format string but '{one}-{two}' will if the hyphen isn't used in {one} or {two}).
    
        We raise if the format string does not match s.
    
        Example:
        fs = '{test}-{flight}-{go}'
        s = fs.format('first', 'second', 'third')
        match_format_string(fs, s) -> {'test': 'first', 'flight': 'second', 'go': 'third'}
        """
    
        # First split on any keyword arguments, note that the names of keyword arguments will be in the
        # 1st, 3rd, ... positions in this list
        tokens = re.split(r'\{(.*?)\}', format_str)
        keywords = tokens[1::2]
    
        # Now replace keyword arguments with named groups matching them. We also escape between keyword
        # arguments so we support meta-characters there. Re-join tokens to form our regexp pattern
        tokens[1::2] = map(u'(?P<{}>.*)'.format, keywords)
        tokens[0::2] = map(re.escape, tokens[0::2])
        pattern = ''.join(tokens)
    
        # Use our pattern to match the given string, raise if it doesn't match
        matches = re.match(pattern, s)
        if not matches:
            raise Exception("Format string did not match")
    
        # Return a dict with all of our keywords and their values
        return {x: matches.group(x) for x in keywords}
    

提交回复
热议问题