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

时间:2018-02-01 00:46:30

标签: ruby regex string heredoc string-interpolation

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

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

我使用此代码生成它:

nowait=True

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

1 个答案:

答案 0 :(得分: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本身提供了&#34;双引号字符串&#34;导致反斜杠被特殊处理的上下文。