我必须重新格式化一堆SQL查询。实际上,像这样的查询会生成语法错误:
insert into table_name (id, name, address) values (4, Pete, My Address Line);
实际上需要
insert into table_name (id, name, address) values (4, "Pete", "My Address Line");
请注意name
和address
。
我在gsub
执行此操作时遇到了困难。我写了以下正则表达式:
regexp = /insert into table_name \(id, name, address \) values \(.+?, (?<name>.+?), (?<address>.+?)\);/
现在想要在命名匹配name
和address
的内容周围添加引号。如何在Ruby中执行此操作?
答案 0 :(得分:1)
这是一种可能性:
sql = "insert into table_name (id, name, address) values (4, Pete, My Address Line);
insert into table_name (id, name, address) values (5, John, My Address Line 2);"
columns_to_replace = %w(name address)
new_sql = sql.gsub(/\((.*?)\) values \((.*?)\)/) do
columns = Regexp.last_match(1).split(', ')
values = columns.zip(Regexp.last_match(2).split(', ')).map do |column, value|
if columns_to_replace.include? column
format('"%s"', value)
else
value
end
end
format('(%s) values (%s)', columns.join(', '), values.join(', '))
end
puts new_sql
# insert into table_name (id, name, address) values (4, "Pete", "My Address Line");
# insert into table_name (id, name, address) values (5, "John", "My Address Line 2");
答案 1 :(得分:0)
r = /
values\s\(\d+,\s+ # match string
\K # discard match so far
([^,]+) # match all characters other than a comma in capture group 1
,\s # match a comma followed by a space
([^)]+) # match all characters other than a right paren in capture group 2
/x # free-spacing regex definition mode
sql = "insert into table_name (id, name, address) values (4, Pete, My Address Line);"
puts sql.sub(r, '"\1", "\2"')
打印
insert into table_name (id, name, address) values (4, "Pete", "My Address Line");
请注意,我无法将values\s\(\d+,\s+
包裹在正面的后方,因为它是可变长度的。正是出于这个原因,我使用了大大低估的\K
指令。
答案 2 :(得分:-1)
wrong_query = "insert into table_name (id, name, address) values (4, Pete, My Address Line);"
right_query = wrong_query.gsub(regexp) do |query|
name = Regexp.last_match(1)
address = Regexp.last_match(2)
[name, address].each do |capture|
query.sub!(capture, '"' + capture + '"')
end
query
end
当名称或地址捕获在整个字符串中不唯一时,这可能会出现严重错误,但对于我的情况,这已经足够了。