2016-05-22 3 views
1

У меня есть простой скрипт Ruby, который читает данные из файла, строка за строкой - это образец данных;Заменить слова в строке на основе начальной буквы каждого слова

"SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020" 
"T001 T665 CAR99A B0932 S222 LA44 V1009 V0029" 

Я пытаюсь найти способ соответствия и замены всего слова на основе первой буквы каждого слова. например. «Sxxxxxx» следует заменить словом «SWT», «Vxxxx» заменить на «VAL»

Ожидает выхода;

"SWR CAR BOT BOT BOT VAL VAL" 
"TNK TNK CAR BOT SWT LTC VAL VAL" 

Образец кода;

File.open('test.txt').each do |line| 
output = line.gsub!('V', 'VAL') 
puts output 

Это то, что я пытался до сих пор (что, очевидно, не работает, поскольку он заменяет любой экземпляр V с VAL)

Это автоматизировать процесс генерации машиночитаемых конфигурационных файлов.

+0

Я думаю, что, наконец, понимаю, что вы хотите делать. Редактировал мой ответ. –

ответ

3

Использование регулярных выражений:

File.open('test.txt').each do |line| 
    output = line.gsub!(/\bV[^\s]*/, 'VAL') 
    puts output 
end 

EDIT:

Для кратному замены я предлагаю использовать хэш вместо что-то вроде case-when и построить регулярное выражение, как показано ниже:

replacements = { 'V' => 'VAL', 'S' => 'SWT' } 
str = "SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020" 
str.gsub(/\b(V|S)[^\s]*/) {|s| replacements[$1] } 
#=> "SWT CAR03 B0932 B23(B) B32(A) VAL VAL" 
+0

Это сработало, но, похоже, оно игнорирует вещи (например) в скобках. Поэтому из моего быстрого теста с помощью '(/ B \ w + /, 'BAN')' дает мне 'BAN (A)', где он должен быть просто «BAN». Любые идеи? – user3788685

+0

@ user3788685, я обновил свой ответ. Пожалуйста, уточните свой вопрос и для большей ясности. – Ilya

+0

Большое спасибо :) Я попробую и узнаю о регулярном выражении - у меня была игра с несколькими онлайновыми сайтами, но там, где не много помощи. Мне нужно запустить еще несколько тестов для более сложных наборов данных, но это работает. – user3788685

0

Поскольку это звучит, как вы хотите сопоставить несколько значений в строке, я не уверен, что вы хотите использовать gsub для этого. Вот пример использования карты. Вы можете добавить любое количество случаев в оператор.

содержимое test.txt

SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020 
T001 T665 CAR99A B0932 S222 LA44 V1009 V0029 

анализатор

results = File.open('test.txt').each.map do |line| 
    mapped_line = line.split.map do |w| 
    case w 
    when /^S/ 
    "SWT" 
    when /^V/ 
    "VAL" 
    else 
    w 
    end 
end 
mapped_line.join " " 
end 
puts results 
+0

Быстрый тест с кодом выкинул ошибки, но из-за требований к выходу и других вещей, которые я выполняю в скрипте, не показанном здесь, метод 'gsub! 'Работал до сих пор и не нарушает ничего вверх по течению. – user3788685

+0

какая ошибка вы получаете? Я побежал, и все получилось. – nPn

+0

undefined method 'each 'for" \ "R101A * R101B R103A * R103B R106A * R106B * R106C-1 * R106C-2 * \" \ n ": String (NoMethodError) Мои данные могут выглядеть как массив, но это не так. Он просто отформатирован таким образом, чтобы машина читала ситуацию. – user3788685

0
SUBS = { "S"=>"SWT", "C"=>"CAR", "B"=>"BOT", "V"=>"VAL", "T"=>"TNK", "L"=>"LTC" } 

def sub(str) 
    str.gsub(/[A-Z0-9\(\)]+/i) { |word| SUBS[word[0]] } 
end 

sub "SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020" 
    #=> "SWT CAR BOT BOT BOT BOT VAL VAL" 
sub "T001 T665 CAR99A B0932 S222 LA44 V1009 V0029" 
    #=> "TNK TNK CAR BOT SWT LTC VAL VAL" 

Это возвращает новую строку, оставляя исходную строку без изменений. Если вы хотите изменить существующую строку, используйте gsub!, а не gsub.

Вариант это создать пустой хэш с блоком по умолчанию, а затем использовать этот хэш в качестве второго аргумента для gsub:

SUBS = Hash.new do |h,k| 
    case k[0] 
    when "S" then "SWT" 
    when "C" then "CAR" 
    when "B" then "BOT" 
    when "V" then "VAL" 
    when "T" then "TNK" 
    when "L" then "LTC" 
    end 

конец

def sub(str) 
    str.gsub(/[A-Z0-9\(\)]+/i, SUBS) 
end 

sub "SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020" 
    #=> "SWT CAR BOT BOT BOT BOT VAL VAL" 
sub "T001 T665 CAR99A B0932 S222 LA44 V1009 V0029" 
    #=> "TNK TNK CAR BOT SWT LTC VAL VAL" 

Смотрите документ String#gsub.

+0

Мои данные могут выглядеть как массив, но его нет. Он просто отформатирован таким образом для последующей обработки. так что на данный момент .gsub! работает – user3788685

Смежные вопросы