【问题标题】:Template literals with nested backticks(`) in ES6ES6 中带有嵌套反引号(`)的模板文字
【发布时间】:2016-06-18 15:43:19
【问题描述】:

如何在 ECMAScript 6 中编写一个包含反引号(`)的模板文字(即嵌套反引号)?

例如:

var query = `
  UPDATE packet
  SET
  `association` = "3485435",
  `tagname` = "associated"
 `

我需要它的原因:

在我上面的代码示例中很明显。

我正在尝试将 node-mysql 查询构建为 Strings 并将它们存储在一个变量中,以便将它们传递给 MySQL。对于UPDATE 样式的查询,MySQL 查询语法需要反引号。

  • 让它们看起来整洁的唯一方法是使用模板文字,否则使用常规单行字符串的查询看起来很糟糕,因为在某些情况下它们最终会很长。

  • 我还想避免使用\n 终止行,因为它很麻烦。

【问题讨论】:

  • 我的直觉是对使用纯模板字符串来构造 SQL 查询的想法感到恐惧,但我猜你的示例中实际上没有任何变量,所以还没有风险。请非常小心(即不要)在此处添加变量插值,除非您使用模板标记函数专门用于构造执行上下文自动转义的查询。
  • @JeremyBanks 嗯,这是 SQL 注入式的问题吗?如果是这种情况,我将使用connection.escape() 处理通过我的API 处理的每个参数。我正在使用包含此方法的node-mysql driver
  • 是的,这是我关心的问题。可以使用connnection.escape() 之类的东西编写安全代码,但这可能会导致您错过一个参数(或者通过一个错误的方式删除转义,等等)。总的趋势是远离任何曾经需要手动转义的东西,转而始终使用 DB 提供的 API 来显式地为查询表达式提供值。看起来node-mysql sort-of 使用了常见的方法,即让您将? 作为查询中值的占位符,并将值作为数组传递。我建议,尽管有问题。
  • 是的。那将是非常合理的,并且可能很好读。我们行业的安全状态是可耻的,而且风险正在迅速升级,所以每当我听到可能表明存在安全问题的事情时,我都会变得非常迂腐和恼火,尽管有时这有点没有根据。 :P
  • 不不,我会说谢谢你让我免于遗漏connection.escape() 参数的风险。

标签: javascript ecmascript-6


【解决方案1】:

来自ES6 In Depth: Template strings by Jason Orendorff

如果您需要在模板字符串中写反引号,则必须使用反斜杠对其进行转义:`\``"`" 相同。

您的查询应该是:

var query = `UPDATE packet
  SET
  \`association\` = "3485435",
  \`tagname\` = "Simos"`

【讨论】:

    【解决方案2】:

    11.8.6 Template Literal Lexical Components

    没有替换的模板定义为

    NoSubstitutionTemplate ::
        ` TemplateCharactersopt`

    模板字符在哪里

    TemplateCharacter ::
        $ [lookahead ≠ { ]
        \ EscapeSequence
        LineContinuation
        LineTerminatorSequence
        SourceCharacter but not one of ` or \ or $ or LineTerminator

    因此,` 不能是模板字符,除非您在它前面加上 \ 对其进行转义。

    【讨论】:

      【解决方案3】:

      正如其他答案中所述,您可以使用反斜杠转义反引号 `,例如 \`

      var tripleBacktickExample = `
      \`\`\`python
      # This JavaScript string contains some example Markdown that
      # uses triple-backticks to delimit a Python code block.
      \`\`\`
      `
      

      但是,如果您在模板文字中连续需要很多反引号`````,则将它们放在占位符内的普通字符串中可能更具可读性,例如${'`````'}${"`````"}

      var tripleBacktickExample = `
      ${'```'}python
      # This JavaScript string contains some example Markdown that
      # uses triple-backticks to delimit a Python code block.
      ${'```'}
      `
      

      【讨论】:

      • @NikKyriakides 在其他答案中只提到了我答案的前半部分。我回答的后半部分展示了一种新技术。我包含了这两种技术的示例,因此可以直接比较它们。
      【解决方案4】:

      如果您想在由撇号组成的字符串中使用撇号,请使用反斜杠对其进行转义,如下所示:

      '\''
      

      同样,如果你想在模板文字中使用反引号,你必须用反斜杠转义它:

      `\``
      

      【讨论】:

        【解决方案5】:

        使用 \`,在最新的 Chrome 中似乎对我有用。

        【讨论】:

        • 在节点 4.8.3 和 chrome \´ 工作 `\´´ 两者都不起作用,后者在其他答案中经常提到
        【解决方案6】:

        我个人认为 ES6 模板文字不适用于 SQL(和Markdown),主要是因为您不能使用反引号字符。我希望他们能添加三引号字符串来正确解决这个问题。

        同时,由于您可能正在使用 ES6 的转译器,您可以考虑使用triplet(免责声明:我是作者)。

        【讨论】:

          【解决方案7】:

          转义所有特殊字符,而不仅仅是反引号:

          let str = '`Hello`\\n${world}';
          let escacped = str.replace(/\\|`|\$/g, '\\$&');
          console.log(eval('`' + escaped + '`') === str); // test
          

          我需要这个来生成一些代码。 str 是 JavaScript 文件的内容,目标是将此内容放入另一个生成的 JavaScript 文件的字符串文字变量中。

          可悲的是,似乎 (2019) 没有用于这种转义的原生 JavaScript 函数。需要替换的字符有:`\$\

          【讨论】:

            【解决方案8】:

            ES6 有新特性:

            • 模板文字
            • 标记模板字面量(标记模板)

            这使得使用字符串更容易。您将文本包装在“反引号”中。

            有了这个,我们可以:

            1. 插值变量

              let foo = "abc";
              
              console.log(`Welcome ${foo}`); // Welcome abc
              
            2. 插入任何类型的表达式

              console.log(`2+3 = ${2+3}`) // 2+3 = 5
              
            3. 用 ' 和 " 引号声明字符串,而不必 逃避任何事情。

              let foo = `foo is 'bar', "bar" is foo`
              
              console.log(foo); // "foo is 'bar', "bar" is foo"
              
            4. 更简洁的多行字符串语法

              let text = `foo is bar
              
              bar is foo`
              
              console.log(text);
              
              //"foo is bar
              
              //bar is foo"
              
            5. 标记模板,我们可以将模板字面量传递给函数,方法如下:

              let person = 'Mike';
              let age = 28;
              
              let output = myTag `that ${ person } is ${ age }`;
              
              function myTag(strings, personExp, ageExp) {
              
                  // strings[0] gets value "that "
                  // strings[1] gets value " is "
                  // personExp  gets value " Mike "
                  // ageStr     gets value "28"
              
                  return strings[0] + personExp + strings[1] + ageExp;
              }
              
              console.log(output);
              
              // that Mike is 28
              
            6. String.raw,我们可以得到原始形式,下面是例子:

              let text = String.raw `The "\n" newline won't result in a new line.'
              console.log(text);
              // The "\n" newline won't result in a new line.
              

            【讨论】:

            • 这没有回答问题。作者已经在使用 ES6 模板字符串,他们想知道如何在其中编写反引号。
            猜你喜欢
            • 2016-11-28
            • 1970-01-01
            • 2016-12-18
            • 1970-01-01
            • 1970-01-01
            • 2019-04-29
            • 2016-07-01
            • 1970-01-01
            • 2016-07-10
            相关资源
            最近更新 更多