Ruby 字符串插值变量但不改变正则表达式
Ruby string interpolate variables but dont alter regex
我需要 return 一个包含正则表达式和内插实例变量的字符串。该字符串需要如下所示:
"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 本身提供了 "double quoted string" 上下文,导致您的反斜杠被特殊对待。
我需要 return 一个包含正则表达式和内插实例变量的字符串。该字符串需要如下所示:
"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 本身提供了 "double quoted string" 上下文,导致您的反斜杠被特殊对待。