【问题标题】:How can I print literal curly-brace characters in a string and also use .format on it?如何在字符串中打印文字花括号字符并在其上使用 .format?
【发布时间】:2022-01-19 14:01:23
【问题描述】:
x = " \{ Hello \} {0} "
print(x.format(42))

给我:Key Error: Hello\\

我要打印输出:{Hello} 42

【问题讨论】:

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

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


【解决方案1】:

试试这个:

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

【讨论】:

    【解决方案2】:

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

    例如:

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

    【讨论】:

      【解决方案3】:

      尝试这样做:

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

      【讨论】:

        【解决方案4】:

        您需要将{{}} 加倍:

        >>> 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
        【解决方案5】:

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

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

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

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

        【讨论】:

          【解决方案6】:

          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 结构和其中的大量双括号
          【解决方案7】:

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

          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/… 中添加了一个简短的演示
          【解决方案8】:

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

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

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

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

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

          【讨论】:

            【解决方案9】:

            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 问题无关。 OP 希望在您通过 .format() 和字典解包方法在链接答案中删除花括号时保留花括号。如果您想在 Python 3.6+ 中保留 {},并且想将值插入字符串,this is the way。这就是手头的问题。我也从未说过 f-strings 可以替代 .format()。你说的。
            • @Gwi 我的意思是,这个问题是关于str.format(),而不是 f-strings,它们不相互兼容。
            【解决方案10】:

            如果需要在字符串中保留两个大括号,则需要在变量的每一侧保留 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}}}}}') 相同的结果。
            【解决方案11】:

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

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

            【讨论】:

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

            我在尝试打印文本时偶然发现了这个问题,我可以将其复制粘贴到 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))
            

            【讨论】:

              【解决方案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】:

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

              >>> 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'
              

              【讨论】:

                【解决方案15】:

                当您只是尝试插入代码字符串时,我建议使用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 类,它对于这种事情来说已经足够强大了。
                【解决方案16】:

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

                【讨论】:

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

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

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

                打印出来的

                {hello} {world}
                

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

                【讨论】:

                  【解决方案18】:

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

                  发件人:

                  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'} 中使用的虚假的“获取集合运算符的单个元素”,= 有效但只会引起混乱!
                  【解决方案19】:

                  如果您需要可格式化的 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 中放置花括号时出现的第一个结果,是的,我同意它并不漂亮,但有时你只需要它。
                  【解决方案20】:

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

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

                  【讨论】:

                    【解决方案21】:

                    我使用了双 {{ }} 来防止 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 语句

                    【讨论】:

                      【解决方案22】:

                      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}")
                      

                      【讨论】:

                        【解决方案23】:

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

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

                        【讨论】:

                          【解决方案24】:

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

                          你只需要把它们加倍。

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

                          所以:

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

                          输出:

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

                          【讨论】:

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

                            输出

                            hello {FOOBAR}
                            

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

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2012-01-10
                              • 2023-01-09
                              • 1970-01-01
                              相关资源
                              最近更新 更多