【问题标题】:Ruby string interpolate variables but dont alter regexRuby 字符串插值变量,但不改变正则表达式
【发布时间】:2018-07-11 05:53:56
【问题描述】:

我需要返回一个包含正则表达式并插入实例变量的字符串。字符串需要如下所示:

"SELECT field1, field2 CASE WHEN REGEXP_CONTAINS(field3, r"^\".*\"$") THEN 'this' WHEN REGEXP_CONTAINS(field3, r"^\[.*]$") THEN 'that' WHEN field3 = '(not provided)' THEN NULL ELSE 'the_other' END AS better_field_3, field4 FROM `interpolated_table_name1` AS tbl LEFT JOIN `interpolated_table_name2` AS tbl2 ON blah = blah"

我用这段代码来生成它:

def string_query
  statement = 
    <<-HEREDOC
      SELECT
        field1,
        field2
        CASE WHEN REGEXP_CONTAINS(field3, r"^\".*\"$") THEN 'this'
          WHEN REGEXP_CONTAINS(field3, r"^\[.*]$") THEN 'that' 
          WHEN field3 = '(not provided)' THEN NULL
          ELSE 'the_other' END AS better_field_3,
        field4
      FROM `#{@dynamic_table_name1}` AS tbl
      LEFT JOIN `#{@dynamic_table_name2}` AS tbl2
        ON blah = blah
    HEREDOC
  statement.squish!
end

字符串用双引号括起来,这就是正则表达式被转义的原因。当我在数据库上运行此 SQL 以执行查询时,正则表达式已被更改,并且未删除要转义的额外反斜杠。

【问题讨论】:

    标签: ruby regex string heredoc string-interpolation


    【解决方案1】:

    就反斜杠转义而言,Heredocs 的行为类似于双引号字符串,因此您必须通过将反斜杠加倍来手动转义它们:

    statement = 
      <<-HEREDOC
        SELECT
          field1,
          field2
          CASE WHEN REGEXP_CONTAINS(field3, r"^\\".*\\"$") THEN 'this'
            WHEN REGEXP_CONTAINS(field3, r"^\\[.*]$") THEN 'that' 
            WHEN field3 = '(not provided)' THEN NULL
            ELSE 'the_other' END AS better_field_3,
          field4
        FROM `#{@dynamic_table_name1}` AS tbl
        LEFT JOIN `#{@dynamic_table_name2}` AS tbl2
          ON blah = blah
      HEREDOC
    

    您也可以取消statement 变量并直接在heredoc 上调用squish(或squish!):

    def string_query
      <<-HEREDOC.squish
        SELECT
          field1,
          field2
          CASE WHEN REGEXP_CONTAINS(field3, r"^\\".*\\"$") THEN 'this'
            WHEN REGEXP_CONTAINS(field3, r"^\\[.*]$") THEN 'that' 
            WHEN field3 = '(not provided)' THEN NULL
            ELSE 'the_other' END AS better_field_3,
          field4
        FROM `#{@dynamic_table_name1}` AS tbl
        LEFT JOIN `#{@dynamic_table_name2}` AS tbl2
          ON blah = blah
      HEREDOC
    end
    

    顺便说一句,我假设 @dynamic_table_name1@dynamic_table_name2 是安全的,因此您不必担心在不转义的情况下将它们插入到您的字符串中。


    这里的双引号:

    r"^\".*\"$"
    

    与 Ruby 如何对待^\".*\"$ 无关。 heredoc 中的双引号只是无意义的字符,它们没有什么特别的。 heredoc 本身提供了“双引号字符串”上下文,导致您的反斜杠被特殊处理。

    【讨论】:

      猜你喜欢
      • 2015-05-16
      • 2016-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多