【问题标题】:How do I print curly-brace characters in a string while using .format?使用 .format 时如何在字符串中打印大括号字符?
【发布时间】:2011-03-29 00:04:53
【问题描述】:

非工作示例:

print(" \{ Hello \} {0} ".format(42))

期望的输出:

 {Hello} 42 

【问题讨论】:

  • 对于那些想要避免双括号 ({{ }}) 的人,请使用 string.Template。在那里,您可以替换 $foo 形式的标识符(便于生成 LaTeX 代码)。
  • 对于那些想要避免双括号,并且不反对在他们的 Python 项目中添加另一个依赖项的人,还有Jinja2 通过允许用户定义的自定义占位符来彻底解决这个问题分隔符语法。

标签: python string format string-formatting curly-braces


【解决方案1】:

您需要将{{}} 加倍:

>>> x = " {{ Hello }} {0} "
>>> print(x.format(42))
' { Hello } 42 '

这是Python documentation for format string syntax的相关部分:

格式字符串包含用大括号 {} 包围的“替换字段”。大括号中不包含的任何内容都被视为文字文本,它会原封不动地复制到输出中。如果您需要在文字文本中包含大括号字符,可以通过将其加倍进行转义:{{}}

【讨论】:

  • 所以如果你想打印“{42}”,你可以使用"{{{0}}}".format(42)
  • 如果你想要一个花括号怎么办? "{ something { } {value}".format(42) 不起作用。
  • "{{".format() 和 "}}".format() 打印单个花括号。在您的示例中: print "{{ something {{ }} {0}".format(42) 将打印 "{ something { } 42"。
  • {0} 是什么意思?
  • @Imray: {0} 指的是.format() 的第一个参数。只要您给.format() 提供相同数量的参数,您就可以打印多个值,例如{0} {1} {2}。有关详细示例,请参阅 docs.python.org/library/string.html#format-examples
【解决方案2】:

Python 3.6+ (2017)

在最新版本的 Python 中,可以使用 f-strings(另请参阅 PEP498)。

对于 f 字符串,应该使用双 {{}}

n = 42  
print(f" {{Hello}} {n} ")

产生所需的

 {Hello} 42

如果您需要解析括号中的表达式而不是使用文字文本,则需要三组括号:

hello = "HELLO"
print(f"{{{hello.lower()}}}")

生产

{hello}

【讨论】:

  • my_greet = "HELLO"你可以得到{hello}作为输出,只使用2组括号,print(f"{ {my_greet.lower()} }")。只需在括号之间留一个空格即可。
  • 如果您在 rona 时代使用 Python3.6+,这应该是现在公认的答案。
  • @Gwi7d31 不,f-strings 不能替代 str.format()。例如,this answer I wrote 不可能使用 f 字符串,因为模板来自输入,而不是源代码。
  • @wjandrea 您的链接确实与 OPs 问题无关。当您通过 .format() 和字典解包方法在链接答案中删除它们时,OP 希望保留花括号。如果您想在 Python 3.6+ 中保留 {},并且想将值插入字符串,this is the way。这就是手头的问题。我也从未说过 f-strings 可以替代 .format()。你说的。
  • @Gwi 我的意思是,这个问题是关于str.format(),而不是 f-strings,它们不相互兼容。
【解决方案3】:

您想用字符{} 格式化字符串

你只需要把它们加倍。

{f'{{'}f'}}' 格式化

所以:

name = "bob"
print(f'Hello {name} ! I want to print }} and {{')

输出:

你好鲍勃!我想打印 } 和 {

【讨论】:

    【解决方案4】:

    你可以通过加倍大括号来逃避它。

    例如:

    x = "{{ Hello }} {0}"
    print(x.format(42))
    

    【讨论】:

      【解决方案5】:
      key = "FOOBAR"
      print(f"hello {{{key}}}")
      

      输出

      hello {FOOBAR}
      

      如果有人想使用 fstrings 在大括号内打印一些东西。

      【讨论】:

        【解决方案6】:

        试试这个:

        x = "{{ Hello }} {0}"

        【讨论】:

          【解决方案7】:

          OP 写了这条评论:

          出于某些目的,我试图格式化一个小的 JSON,例如:'{"all": false, "selected": "{}"}'.format(data) 以获得类似 {"all": false, "selected": "1,2"} 的东西

          在处理 JSON 时出现“转义大括号”问题是很常见的。

          我建议这样做:

          import json
          data = "1,2"
          mydict = {"all": "false", "selected": data}
          json.dumps(mydict)
          

          它比替代方案更干净,即:

          '{{"all": false, "selected": "{}"}}'.format(data)
          

          当 JSON 字符串比示例更复杂时,使用 json 库绝对是更可取的。

          【讨论】:

          • 阿门!这似乎需要更多的工作,但使用库来做图书馆应该做的事情,而不是偷工减料……可以做更好的事情。
          • 但是不能保证 Python 对象中键的顺序......不过,JSON 库保证以 JSON 方式序列化。
          • wizzwizz4:好点。从 Python 3.6 开始,字典是按插入顺序排列的,所以这不是问题。 2.7 和 3.5 之间的 Python 版本可以使用集合库中的 OrderedDict。
          • 如果是data = 'foo"',替代方案也是非常错误的,因为data 的值中的" 将无法正确转义。
          • 如果您正在处理 JSON,那么此答案适合您。它在可读性和可维护性方面胜出——想象一下处理复杂的 JSON 结构和其中的大量双括号
          【解决方案8】:

          f-strings (python 3)

          您可以避免将大括号加倍所有文字的常规(哑)字符串,可能包含“不安全”特殊字符。 Let python do the string joining 只需将多个字符串堆叠在一起即可。

          number = 42
          print(" { Hello }"  
          f" {number} " 
          "{ thanks for all the fish }")
          
          ### OUTPUT:
          { Hello } 42 { thanks for all the fish }
          

          注意:字符串之间的换行不是必需的。我添加它们只是为了便于阅读。也可以将上面的代码写成如下图:

          ⚠️ 警告:这可能会伤害您的眼睛或让您头晕目眩!

          print("{Hello}"f"{number}""{thanks for all the fish}")
          

          【讨论】:

            【解决方案9】:

            我参加这个聚会迟到可笑。我成功地将括号放在替换元素中,如下所示:

            print('{0} {1}'.format('{hello}', '{world}'))
            

            打印出来的

            {hello} {world}
            

            严格来说,这不是 OP 所要求的,因为他/她想要格式字符串中的大括号,但这可能会对某人有所帮助。

            【讨论】:

              【解决方案10】:

              尝试这样做:

              x = " {{ Hello }} {0} "
              print x.format(42)
              

              【讨论】:

                【解决方案11】:

                如果您只想打印花括号的一侧:

                a=3
                print(f'{"{"}{a}')
                >>> {3
                

                【讨论】:

                  【解决方案12】:

                  我使用了双 {{ }} 来防止 fstring 值注入,

                  例如,这是我的 Postgres UPDATE 语句来更新一个整数数组列,该列采用 {} 的表达式来捕获数组,即:

                  端口 = '{100,200,300}'

                  使用 fstrings,

                  ports = [1,2,3]
                  
                  query = f"""
                     UPDATE table SET ports = '{{{ports}}}' WHERE id = 1
                  """
                  
                  

                  实际的查询语句是,

                  UPDATE table SET ports = '{1,2,3}'
                  

                  这是一个有效的 postgres 语句

                  【讨论】:

                    【解决方案13】:

                    我最近遇到了这个问题,因为我想将字符串注入到预先格式化的 JSON 中。 我的解决方案是创建一个辅助方法,如下所示:

                    def preformat(msg):
                        """ allow {{key}} to be used for formatting in text
                        that already uses curly braces.  First switch this into
                        something else, replace curlies with double curlies, and then
                        switch back to regular braces
                        """
                        msg = msg.replace('{{', '<<<').replace('}}', '>>>')
                        msg = msg.replace('{', '{{').replace('}', '}}')
                        msg = msg.replace('<<<', '{').replace('>>>', '}')
                        return msg
                    

                    然后您可以执行以下操作:

                    formatted = preformat("""
                        {
                            "foo": "{{bar}}"
                        }""").format(bar="gas")
                    

                    在性能不是问题的情况下完成工作。

                    【讨论】:

                    • 简单优雅地集成到现有代码中,几乎不需要修改。谢谢!
                    • 当然,假设您的文本从不包含任何&lt;&lt;&lt;&gt;&gt;&gt;,否则它们会被覆盖。最好使用逃生策略来提高可靠性!
                    • 你建议的逃生策略是什么?无论如何,您知道您的模板文本,并且可以修改魔术字符串以防您担心冲突。
                    【解决方案14】:

                    您可以使用“引用墙”将格式化字符串部分与常规字符串部分分开。

                    发件人:

                    print(f"{Hello} {42}")
                    

                    print("{Hello}"f" {42}")
                    

                    一个更清晰的例子是

                    string = 10
                    print(f"{string} {word}")
                    

                    输出:

                    NameError: name 'word' is not defined
                    

                    现在,像这样添加报价墙:

                    string = 10
                    print(f"{string}"" {word}")
                    

                    输出:

                    10 {word}
                    

                    【讨论】:

                    • 这看起来更像是串联,但思路不错
                    • 我建议不要这样做 - 它使用的语言特性本身是有争议的,被 Guido 描述为错误(隐式字符串连接),并以一种本身不寻常的方式使用它因此令人困惑。许多遇到此问题的人将很难弄清楚发生了什么。它本质上只是 f"{string}" + " {word}" 简单明了,但这样做更令人困惑。它让我想起了在 elem ,= {'single_element'} 中使用的虚假的“获取集合运算符的单个元素”,= 有效但只会引起混乱!
                    【解决方案15】:

                    如果需要在字符串中保留两个大括号,则需要在变量的每一侧保留 5 个大括号。

                    >>> myvar = 'test'
                    >>> "{{{{{0}}}}}".format(myvar)
                    '{{test}}'
                    

                    【讨论】:

                    • 对于那些使用 f-strings 的人,在两边使用 4 个花括号而不是 5 个
                    • @TerryA .format 和 f 字符串之间的大括号行为没有区别。代码a = 1; print('{{{{{a}}}}}'.format(a=a)) 产生与a = 1; print(f'{{{{{a}}}}}') 相同的结果。
                    【解决方案16】:

                    虽然不是更好,仅供参考,你也可以这样做:

                    >>> x = '{}Hello{} {}'
                    >>> print x.format('{','}',42)
                    {Hello} 42
                    

                    例如,当有人想要打印{argument} 时,它可能很有用。它可能比'{{{}}}'.format('argument')更具可读性

                    请注意,您在 Python 2.7 之后省略了参数位置(例如 {} 而不是 {0}

                    【讨论】:

                      【解决方案17】:

                      如果您想打印一个大括号(例如{),您可以使用{{,如果您愿意,您可以稍后在字符串中添加更多大括号。 例如:

                      >>> f'{{ there is a curly brace on the left. Oh, and 1 + 1 is {1 + 1}'
                      '{ there is a curly brace on the left. Oh, and 1 + 1 is 2'
                      

                      【讨论】:

                        【解决方案18】:

                        如果您要经常这样做,最好定义一个实用函数,让您可以使用任意大括号替换,例如

                        def custom_format(string, brackets, *args, **kwargs):
                            if len(brackets) != 2:
                                raise ValueError('Expected two brackets. Got {}.'.format(len(brackets)))
                            padded = string.replace('{', '{{').replace('}', '}}')
                            substituted = padded.replace(brackets[0], '{').replace(brackets[1], '}')
                            formatted = substituted.format(*args, **kwargs)
                            return formatted
                        
                        >>> custom_format('{{[cmd]} process 1}', brackets='[]', cmd='firefox.exe')
                        '{{firefox.exe} process 1}'
                        

                        请注意,这将适用于作为长度为 2 的字符串的括号或两个字符串的可迭代(用于多字符分隔符)。

                        【讨论】:

                        • 也考虑过。当然,这也可以,而且算法更简单。但是,假设你有很多这样的文本,你只想在这里和那里参数化它。每次创建输入字符串时,您都不想手动替换所有这些大括号。您只想在这里和那里“插入”您的参数化。在这种情况下,我认为从用户的角度来看,这种方法更容易思考和完成。我受到 linux 的“sed”命令的启发,该命令具有类似的功能,可以根据方便任意选择分隔符。
                        • 简而言之,我宁愿实用函数稍微复杂一点,而不是让@$$ 每次都使用起来很痛苦。如果我误解了您的提议,请告诉我。
                        • 我已经在我的 public.lab 空间 github.com/dreftymac/public.lab/blob/master/topic/python/… 中添加了一个简短的演示
                        【解决方案19】:

                        原因是,{}.format() 的语法,所以在您的情况下,.format() 无法识别 {Hello},因此它引发了错误。

                        您可以使用双花括号 {{}} 覆盖它,

                        x = " {{ Hello }} {0} "
                        

                        尝试%s 进行文本格式化,

                        x = " { Hello } %s"
                        print x%(42)  
                        

                        【讨论】:

                          【解决方案20】:

                          您可以使用原始字符串方法来做到这一点,只需在字符串前添加不带引号的字符 'r'。

                          # to print '{I am inside braces}'
                          print(r'{I am inside braces}')
                          

                          【讨论】:

                          • 您好!您可能需要重新检查; Python 3.7 打印 \{I am inside braces\}.
                          • @Teodor 对此感到抱歉。现在我通过打印为原始字符串来解决这个问题。
                          【解决方案21】:

                          我在尝试打印文本时偶然发现了这个问题,我可以将其复制粘贴到 Latex 文档中。我扩展 this answer 并使用命名替换字段:

                          假设您想打印出多个变量的乘积,其索引如下 ,在 Latex 中为 $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ 以下代码使用命名字段完成这项工作,以便对于许多索引它保持可读性:

                          idx_mapping = {'i1':42, 'i2':3141, 'i3':2178 }
                          print('$A_{{ {i1:04d} }} * A_{{ {i2:04d} }} * A_{{ {i3:04d} }} * A_{{ {i1:04d} }}$'.format(**idx_mapping))
                          

                          【讨论】:

                            【解决方案22】:

                            当您只是尝试插入代码字符串时,我建议使用jinja2,它是 Python 的全功能模板引擎,即:

                            from jinja2 import Template
                            
                            foo = Template('''
                            #include <stdio.h>
                            
                            void main() {
                                printf("hello universe number {{number}}");
                            }
                            ''')
                            
                            for i in range(2):
                                print(foo.render(number=i))
                            

                            所以你不会被强制复制花括号,因为一大堆其他答案建议

                            【讨论】:

                            • 我同意避免重复花括号是一件好事——但与其使用 jinja2,我只需要使用 python 自己的 string.Template 类,它对于这种事情来说已经足够强大了。
                            【解决方案23】:

                            使用转义序列来转义 f 字符串中的花括号。例如:print(f'{a={1}}')

                            【讨论】:

                            • OP 确实使用了转义序列并报告它们不起作用。此处的示例无法编译。此答案不会为之前发布的十五个答案增加任何价值。
                            【解决方案24】:

                            如果您需要可格式化的 f 字符串模板中的花括号,则需要在 f 字符串的一组花括号中输出一个包含两个花括号的字符串:

                            css_template = f"{{tag}} {'{{'} margin: 0; padding: 0;{'}}'}"
                            for_p = css_template.format(tag="p")
                            # 'p { margin: 0; padding: 0;}'
                            

                            【讨论】:

                            • 这个问题与 f-strings 无关,而 IMO 以这种方式将 f-strings 和格式结合起来会产生非常不可读的代码
                            • 这是当你谷歌如何在 python f-strings 中放置花括号时出现的第一个结果,是的,我同意它并不漂亮,但有时你只需要它。
                            【解决方案25】:

                            或者只是参数化括号本身?可能非常冗长。

                            x = '{open_bracket}42{close_bracket}'.format(open_bracket='{', close_bracket='}') 
                            print(x)
                            # {42}
                            

                            【讨论】:

                              猜你喜欢
                              • 2012-01-10
                              • 2022-01-19
                              • 1970-01-01
                              • 2015-04-05
                              相关资源
                              最近更新 更多