Ruby 字符串插值变量,但不更改正则表达式



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

"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 以执行查询时,正则表达式已被更改,并且没有删除用于转义的额外反斜杠。

就反斜杠转义而言,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 本身提供了"双引号字符串"上下文,导致您的反斜杠被特殊处理。

相关内容

  • 没有找到相关文章

最新更新