Вопрос по ruby, ruby-on-rails-3 – Разделить строку без удаления разделителя

10

Мне нужно проанализировать файл, чтобы получить отдельные операторы SQL и запустить их из контроллера rails.

У меня есть следующий код:

@sql_file = "#{RAILS_ROOT}/lib/evidence_interface_import.sql"   
@sql_stmts_array = File.read(@sql_file).split(";")  

@sql_stmts_array.each_with_index do |sql_stmt,s_index|
   ActiveRecord::Base.connection.execute(sql_stmt)
end

Разделение удаляет & quot ;; & quot; с конца SQL. Есть ли способ не удалять & quot ;; & quot; и все еще разделяется с помощью & quot ;; & quot ;.

Ваш Ответ

5   ответов
1

scan с соответствующим регулярным выражением, которое должно дать вам результаты, аналогичныеsplit, но если вы хотите придерживаться пути без регулярных выражений, вы можете просто добавить точку с запятой к каждой ячейке в массиве:

@sql_stmts_array = File.read(@sql_file).split(";").each do |s|
  s << ";"
end
Это имеет побочный эффект - ставить точку с запятой после последней записи.
Разве это не то, что нужно? Не должно быть; после каждой записи?
8

Когда используешьActiveRecord::Base.connection.execute Вы не должны включать точку с запятой в первую очередь.

Кроме того, другой способ разделения без удаления разделителя - использовать группы, как показано в следующем примере:

"a;b;c".split(/;/)   # => ["a", "b", "c"]

"a;b;c".split(/(;)/) # => ["a", ";", "b", ";", "c"]
Я бы отметил это как принятый ответ.scan Кажется, нужен разделитель после каждого элемента, а не только между ними.
для многих случаев, связанных с токенизацией и манипулированием строками - это отличное решение.
4

@sql_stmts_array = File.read(@sql_file).lines(separator=';')
Синтаксис неверен дляlines(separator=';') - это будет работать, но плохо написано. Так должно бытьlines(';') вместо. Но используйтеFile.readlines(@sql_file, ';') вместо этого, потому что он короче и выполняет то же самое.
13

Ага,scan Это:

'a; b; c;'.scan(/[^;]*;/)
#=> ["a;", " b;", " c;"]

Вы можете избавиться от лишних пробелов, взглянув наmap(&:strip) после, но это, вероятно, здесь не нужно.

Обратите внимание, что это очень элементарно, и что-то вроде строкового литерала в SQL с точкой с запятой сломает это. (Например.select * from stuff where name = ";";.)

Аналогичный вариант будет:'a; b; c;'.scan(/.*?;/)
4

Используйте регулярное выражение с видом сзади

split(/(?<=;)/)

Похожие вопросы