def format_string(f, val, grouping=False):
percents = list(_percent_re.finditer(f))<EOL>new_f = _percent_re.sub('<STR_LIT:%s>', f)<EOL>if isinstance(val, collections.abc.Mapping):<EOL><INDENT>new_val = []<EOL>for perc in percents:<EOL><INDENT>if perc.group()[-<NUM_LIT:1>]=='<STR_LIT:%>':<EOL><INDENT>new_val.append('<STR_LIT:%>')<EOL><DEDENT>else:<EOL><INDENT>new_val.append(format(perc.group(), val, grouping))<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>if not isinstance(val, tuple):<EOL><INDENT>val = (val,)<EOL><DEDENT>new_val = []<EOL>i = <NUM_LIT:0><EOL>for perc in percents:<EOL><INDENT>if perc.group()[-<NUM_LIT:1>]=='<STR_LIT:%>':<EOL><INDENT>new_val.append('<STR_LIT:%>')<EOL><DEDENT>else:<EOL><INDENT>starcount = perc.group('<STR_LIT>').count('<STR_LIT:*>')<EOL>new_val.append(_format(perc.group(),<EOL>val[i],<EOL>grouping,<EOL>False,<EOL>*val[i+<NUM_LIT:1>:i+<NUM_LIT:1>+starcount]))<EOL>i += (<NUM_LIT:1> + starcount)<EOL><DEDENT><DEDENT><DEDENT>val = tuple(new_val)<EOL>return new_f % val<EOL>
Formats a string in the same way that the % formatting would use,
    but takes the current locale into account.
    Grouping is applied if the third parameter is true.