2016-05-22 150 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 

編輯:

對於多次更換,我建議使用哈希,而不是像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

未定義的方法'each'用於「\」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

相關問題