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