此Postgres命令在从psql
命令行运行时删除所有反斜杠:
UPDATE table SET column = REGEXP_REPLACE(column, '\B', '', 'g');
此Rails命令不起作用(它运行时没有错误,但不会删除反斜杠):
ActiveRecord::Base.connection.execute("UPDATE table SET column = REGEXP_REPLACE(column, '\B', '', 'g'))
看起来Rails更改了查询并运行它(我检查了在控制台中运行查询的输出):
UPDATE table SET column = REGEXP_REPLACE(column, 'B', '', 'g')
Postgres命令在从psql
命令行运行时也成功删除了反斜杠:
UPDATE table SET column = REGEXP_REPLACE(column, '\\', '', 'g')
使用Rails运行时,同样的Postgres命令出错了:
ActiveRecord::Base.connection.execute("UPDATE table SET column = REGEXP_REPLACE(column, '\\', '', 'g')")
这是错误:
PG :: InvalidRegularExpression:错误:正则表达式无效: 无效的转义\序列
这是我Gemfile
中设置的Postgres版本:
gem 'pg', '>= 0.18', '< 2.0'
你能解释为什么我收到这个错误以及如何编写Rails代码来删除列中的所有反斜杠?这将在大型数据集上运行,我需要快速解决方案。
答案 0 :(得分:1)
您想要做的事情很复杂,因为有多种事情需要以自己的方式解释\
:
\
表示Ruby中双引号字符串中的内容。所以"\B"
只是在Ruby中编写"B"
的一种误导和复杂的方式。您需要说"\\B"
以获取包含两个字符\B
的字符串。
\
表示PostgreSQL正则表达式中的内容。因此在PostgreSQL的正则表达式中存在\B
,这样你在查看另一种语言中的\
之类的东西时就不必计算\\\\
,你只需要稍微不那么丑陋的东西比如\\B
。
要解决您的问题,您可以正确地逃避逃脱:
ActiveRecord::Base.connection.execute("UPDATE table SET column = REGEXP_REPLACE(column, '\\B', '', 'g')")
当数据库看到时,它会看到:
UPDATE table SET column = REGEXP_REPLACE(column, '\B', '', 'g')
因为\\
表示在双引号Ruby字符串中“只给我一个\
”。
我可能会进一步简化并使用SQL replace
function:
replace(string text, from text, to text)
将子字符串的字符串中的所有匹配项替换为,将子字符串替换为。
与Ruby中的%q{...}
字符串结合使用:
ActiveRecord::Base.connection.execute(%q{
update table
set column = replace(column, '\', '')
})
%q{...}
摆脱了一个转义问题,因为它在Ruby中就像一个单引号字符串,因此\
并不意味着什么特别的。在SQL中使用replace
可以解决另一个转义问题,因为它只适用于普通的旧字符串(而不是字符串表示的正则表达式),因此\
再次没有任何意义。