Python 将字符串中的大括号转义为未定义次数的格式

Python 将字符串中的大括号转义为未定义次数的格式,python,python-2.7,escaping,string-formatting,python-2.x,Python,Python 2.7,Escaping,String Formatting,Python 2.x,相关: string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}" print string.format(format='string') string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal c

相关:

string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
print string.format(format='string')
string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='string1').format(format2='string2')
string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='{format2}').format(format2='string')
string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"

if fooCondition:
    string = string.format('{} bar')
    if barCondition:
        string = string.format('{} baz')
        if bazCondition:
            string = string.format('{} buzz')
string = string.format('foo')

print string
string = "{} {{DRY - Don't repeat yourself!}}"

if fooCondition:
    string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    if barCondition:
        string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if bazCondition:
            string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
string = string.format('foo')

print string
使用大括号(
{•••}
)表示要格式化的字符串部分。如果要使用文字大括号字符,以便它们被
.format()
忽略,可以使用双大括号(
{{•••}}
MCVE:

string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
print string.format(format='string')
string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='string1').format(format2='string2')
string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='{format2}').format(format2='string')
string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"

if fooCondition:
    string = string.format('{} bar')
    if barCondition:
        string = string.format('{} baz')
        if bazCondition:
            string = string.format('{} buzz')
string = string.format('foo')

print string
string = "{} {{DRY - Don't repeat yourself!}}"

if fooCondition:
    string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    if barCondition:
        string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if bazCondition:
            string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
string = string.format('foo')

print string
如果有一系列的
.format()
s,则每次使用
.format()
时,大括号的数量将增加一倍。最后一个由4个大括号包围,并在最终输出中以文字大括号结束MCVE:

string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
print string.format(format='string')
string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='string1').format(format2='string2')
string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='{format2}').format(format2='string')
string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"

if fooCondition:
    string = string.format('{} bar')
    if barCondition:
        string = string.format('{} baz')
        if bazCondition:
            string = string.format('{} buzz')
string = string.format('foo')

print string
string = "{} {{DRY - Don't repeat yourself!}}"

if fooCondition:
    string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    if barCondition:
        string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if bazCondition:
            string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
string = string.format('foo')

print string
也可以将另一个格式字符串格式化为格式字符串。最后一个由4个大括号包围,并在最终输出中以文字大括号结束MCVE:

string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
print string.format(format='string')
string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='string1').format(format2='string2')
string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='{format2}').format(format2='string')
string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"

if fooCondition:
    string = string.format('{} bar')
    if barCondition:
        string = string.format('{} baz')
        if bazCondition:
            string = string.format('{} buzz')
string = string.format('foo')

print string
string = "{} {{DRY - Don't repeat yourself!}}"

if fooCondition:
    string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    if barCondition:
        string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if bazCondition:
            string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
string = string.format('foo')

print string
根据运行时确定的条件,使用
.format()
s链时会出现问题。若您想将一组大括号转义为文字字符,您会使用多少MCVE:

string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
print string.format(format='string')
string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='string1').format(format2='string2')
string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
print string.format(format1='{format2}').format(format2='string')
string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"

if fooCondition:
    string = string.format('{} bar')
    if barCondition:
        string = string.format('{} baz')
        if bazCondition:
            string = string.format('{} buzz')
string = string.format('foo')

print string
string = "{} {{DRY - Don't repeat yourself!}}"

if fooCondition:
    string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    if barCondition:
        string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if bazCondition:
            string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
string = string.format('foo')

print string
字符串的第一部分有4种可能的输出:

  • foo

  • foo-bar

  • foo baz bar

  • foo buzz baz bar

  • 字符串的第二部分以不同数量的大括号结束,这取决于有多少条件是
    True
    。我希望第二部分的花括号保持永久转义,比如不要每次调用
    .format()
    时都“脱落一层”。我可以这样解决问题,MCVE:

    string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
    print string.format(format='string')
    
    string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
    print string.format(format1='string1').format(format2='string2')
    
    string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
    print string.format(format1='{format2}').format(format2='string')
    
    string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"
    
    if fooCondition:
        string = string.format('{} bar')
        if barCondition:
            string = string.format('{} baz')
            if bazCondition:
                string = string.format('{} buzz')
    string = string.format('foo')
    
    print string
    
    string = "{} {{DRY - Don't repeat yourself!}}"
    
    if fooCondition:
        string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if barCondition:
            string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
            if bazCondition:
                string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    string = string.format('foo')
    
    print string
    

    MCVE不是我真正的代码。我的真实代码运行在Google App Engine web服务器上。它是超长而复杂的。我正在处理字符串中的HTML、CSS和JavaScript。我想通过
    .format()
    将内容插入HTML,而不会弄乱CSS和JS的大括号。我当前的实现是不可伸缩的,并且非常容易出错。我必须管理多达5个连续的花括号(如:
    {{{{{{••••}}}}
    )才能不动地通过
    .format()
    链。我需要定期将大括号重新插入到没有固定次数格式化的字符串中。修复此意大利面代码的优雅方法是什么


    如何在Python格式字符串中永久转义大括号?

    简单而明显的解决方案是,不要将
    .format()
    应用于无法完全控制的字符串。相反,也许是这样

    result = thestring.replace('{postURL}', url).replace('{postTitle}', title)
    

    我创建了一个partialformat函数(在python3.x中),该函数重写stringformat方法,只允许格式化字符串中需要格式化的部分。编辑:我还包括了一个Python2版本

    ## python 3x version
    import string
    from _string import formatter_field_name_split
    ################################################################################
    def partialformat(s: str, recursionlimit: int = 10, **kwargs):
        """
        vformat does the acutal work of formatting strings. _vformat is the 
        internal call to vformat and has the ability to alter the recursion 
        limit of how many embedded curly braces to handle. But for some reason 
        vformat does not.  vformat also sets the limit to 2!   
    
        The 2nd argument of _vformat 'args' allows us to pass in a string which 
        contains an empty curly brace set and ignore them.
        """
    
        class FormatPlaceholder(object):
            def __init__(self, key):
                self.key = key
    
            def __format__(self, spec):
                result = self.key
                if spec:
                    result += ":" + spec
                return "{" + result + "}"
    
            def __getitem__(self, item):
                return
    
        class FormatDict(dict):
            def __missing__(self, key):
                return FormatPlaceholder(key)
    
        class PartialFormatter(string.Formatter):
            def get_field(self, field_name, args, kwargs):
                try:
                    obj, first = super(PartialFormatter, self).get_field(field_name, args, kwargs)
                except (IndexError, KeyError, AttributeError):
                    first, rest = formatter_field_name_split(field_name)
                    obj = '{' + field_name + '}'
    
                    # loop through the rest of the field_name, doing
                    #  getattr or getitem as needed
                    for is_attr, i in rest:
                        if is_attr:
                            try:
                                obj = getattr(obj, i)
                            except AttributeError as exc:
                                pass
                        else:
                            obj = obj[i]
    
                return obj, first
    
        fmttr = PartialFormatter()
        try:
            fs, _ = fmttr._vformat(s, ("{}",), FormatDict(**kwargs), set(), recursionlimit)
        except Exception as exc:
            raise exc
        return fs
    
    编辑:看起来Python2.x有一些细微的区别

    ## python 2.x version
    import string
    formatter_field_name_split = str._formatter_field_name_split
    def partialformat(s, recursionlimit = 10, **kwargs):
        """
        vformat does the acutal work of formatting strings. _vformat is the 
        internal call to vformat and has the ability to alter the recursion 
        limit of how many embedded curly braces to handle. But for some reason 
        vformat does not.  vformat also sets the limit to 2!   
    
        The 2nd argument of _vformat 'args' allows us to pass in a string which 
        contains an empty curly brace set and ignore them.
        """
    
        class FormatPlaceholder(object):
            def __init__(self, key):
                self.key = key
    
            def __format__(self, spec):
                result = self.key
                if spec:
                    result += ":" + spec
                return "{" + result + "}"
    
            def __getitem__(self, item):
                return
    
        class FormatDict(dict):
            def __missing__(self, key):
                return FormatPlaceholder(key)
    
        class PartialFormatter(string.Formatter):
            def get_field(self, field_name, args, kwargs):
                try:
                    obj, first = super(PartialFormatter, self).get_field(field_name, args, kwargs)
                except (IndexError, KeyError, AttributeError):
                    first, rest = formatter_field_name_split(field_name)
                    obj = '{' + field_name + '}'
    
                    # loop through the rest of the field_name, doing
                    #  getattr or getitem as needed
                    for is_attr, i in rest:
                        if is_attr:
                            try:
                                obj = getattr(obj, i)
                            except AttributeError as exc:
                                pass
                        else:
                            obj = obj[i]
    
                return obj, first
    
        fmttr = PartialFormatter()
        try:
            fs = fmttr._vformat(s, ("{}",), FormatDict(**kwargs), set(), recursionlimit)
        except Exception as exc:
            raise exc
        return fs
    
    用法:

    class ColorObj(object):
        blue = "^BLUE^"
    s = '{"a": {"b": {"c": {"d" : {} {foo:<12} & {foo!r} {arg} {color.blue:<10} {color.pink} {blah.atr} }}}}'
    print(partialformat(s, foo="Fooolery", arg="ARRrrrrrg!", color=ColorObj))
    

    我的解决方案:

    string = "{format} {{This part won't be formatted. The final string will have literal curly braces here.}}"
    print string.format(format='string')
    
    string = "{format1} {{format2}} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
    print string.format(format1='string1').format(format2='string2')
    
    string = "{format1} {{{{3rd one won't be formatted. The final string will have literal curly braces here.}}}}"
    print string.format(format1='{format2}').format(format2='string')
    
    string = "{} {{{{{{Here I don't know exactly how many curly braces to use because this string is formatted differently due to conditions that I have no control over.}}}}}}"
    
    if fooCondition:
        string = string.format('{} bar')
        if barCondition:
            string = string.format('{} baz')
            if bazCondition:
                string = string.format('{} buzz')
    string = string.format('foo')
    
    print string
    
    string = "{} {{DRY - Don't repeat yourself!}}"
    
    if fooCondition:
        string = string.format('{} bar').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
        if barCondition:
            string = string.format('{} baz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
            if bazCondition:
                string = string.format('{} buzz').replace("{DRY - Don't repeat yourself!}", "{{DRY - Don't repeat yourself!}}")
    string = string.format('foo')
    
    print string
    
    我用模糊的Unicode字符替换字符串中的“永久”大括号,我确信我永远不会将其用于任何其他用途

    例如:

    • 我键入“——”表示“{”

    • 我键入“——”表示“}”

    在完成所有格式设置之后,我用相应的大括号替换每个替换字符

    stringAfterFormatting.replace("⁍", "{").replace("⁌", "}")
    
    不管我在字符串上使用多少次链式和嵌套的
    .format()
    s

    string.format(•••).format(•••).format(•••).replace("⁍", "{").replace("⁌", "}")
    

    我格式化需要格式化的内容,并替换()最后的大括号。

    您永远不应该使用字符串格式来生成代码。使用适当的模板语言。您可以在问题中永久提供相关代码。然后您的问题太广泛,无法回答,因此我不知道我们可以提供什么帮助。您的输入和预期输出是什么?如何在字符串上使用
    format()
    ?如果我们不知道细节,我们就无能为力。Unicode专门为这样的东西保留了一个私人使用区域。你不必使用罕见的字符;你可以使用一个保证不会被公众使用的。(一些流行字体使用PUA代码点,这可能导致“泄漏”,因此在提交之前,可能需要谷歌搜索您想要使用的字符代码。)