2011-07-23 179 views
1

我正在爲獨立遊戲DwarfFortress開發一個模塊的最後階段。在MOD處於工作狀態之前需要做的最後一件事是通過並改變Dwarf Fortress RAWs - 包含數百種填充遊戲的生物的信息的二十多個文本文件。查找並替換文本文件目錄中的單詞

從技術角度來看,這是通過一個文本文件目錄,並基本上執行「查找和替換」操作來改變每一行。

我的大部分編程經驗都是面向對象的語言--C#和Java,以及一些Assembler和C的經驗。但是,這些語言都不適合這種任務。

其中一個可能會是一個非常簡單的替代品,就是因爲矮人堡壘RAW的編寫方式,我不知道是否需要更換該行,直到進一步放下文本文件。以下是一個簡短的示例場景。

[CREATURE:WOLF] 
    ... 
    [Many irrelevant lines of tokens] 
    ... 
[BODY_DETAIL_PLAN:STANDARD_MATERIALS] 
[BODY_DETAIL_PLAN:STANDARD_TISSUES] 
    ... 
    [Many more irrelevant lines of tokens] 
    ... 
[MULTIPLY_VALUE:2] 

我希望寫需要能夠通過對讀取到的程序[MULTIPLY_VALUE:X]線,然後返回並替換包含兩行:與[BODY_DETAIL_PLAN Z] [BODY_DETAIL_PLAN:Y],其中Y的變化取決於X的讀取值

我可以保證兩兩件事:

  • 一個[MULTIPLY_VALUE:X]行會之間出現[生物:A]和[生物: B]或[CREATURE:Z]和文件的結尾。
  • [MULTIPLY_VALUE:X]行會始終在之後行[BODY_DETAIL_PLAN:Z]行,如果它出現在該生物上。

基於我所擁有的編碼經驗,我最接近一個可行的想法是編寫一個C程序來讀取文件,使用指針來'保存'讀取行的位置,並在文件閱讀器檢測到新RAW的開始。

但是,這讓我覺得不夠優雅,並且遇到了麻煩,因爲我沒有經驗在C(或任何語言)中實現查找/替換功能。

是否有一些更簡單的方法來完成這個手工審閱每個文本文件的單調任務?我完全願意學習一種新的編程語言,但我不完全知道哪種語言最容易處理這種情況。

對此提出建議?

+1

看起來像Perl,Python或Ruby等腳本語言的完美任務。那些語言在早餐上做這種事情。一個問題雖然..可以在文件中的其他地方有一個MULTIPLY行嗎?即你是否需要智能來在CREATURE段中找到它,或者你是否可以盲目地替換整個文件中的任何MULTIPLY行? – Casper

+0

@Casper - 是的,我認爲腳本語言可能工作,但我沒有腳本語言的經驗,因此是一個問題。問題在於它不是需要替換的MULTIPLY行,而是MULTIPLY行的存在決定了用*替換單獨行的方式。 –

回答

1

好吧,我之前提出問題的原因是我想知道被替換的行的上下文是否重要。因爲如果上下文不重要,那麼整個遞歸替換的東西將主要是一個單線程程序。

根據你的回答,我假設需要考慮上下文。因此,這裏是Ruby中的簡化示例。只是一個例子,所以你可以看到它是如何工作的。代碼有點冗長,以幫助您更好地理解它。你可以用它作爲基礎並從那裏開始工作。

的程序是這樣的 - 假設你有一個數據文件data.txt像這樣:

[aaa] 
[bbb] 
[replace:a] 
[replace:b] 

[start_marker] 
    [xxx] 
    [replace:x] 
    [replace:y] 
    [yyy] 
[end_marker] 

[replace:c] 
[replace:d] 
[ccc] 
[ddd] 

運行程序:

ruby replace.rb data.txt 

而且你最終data.txt.bak與原始數據,並替換爲data.txt,看起來像這樣:

[aaa] 
[bbb] 
[replace:a] 
[replace:b] 

[start_marker] 
    [xxx] 
    [replace:x was replaced!] 
    [replace:y was replaced!] 
    [yyy] 
[end_marker] 

[replace:c] 
[replace:d] 
[ccc] 
[ddd] 

程序replace.rb

require 'rubygems' 
require 'ftools'   # File.move 
require 'extensions/io' # File.writelines 

file = ARGV.shift 
lines = File.open(file).readlines 

replace_these = Array.new 
within_section = false 

# Loop until we hit start_marker, then store potential 
# lines until we hit end_marker, then fix the lines 
lines.each { |line| 
    within_section = true if line.match /\[start_marker\]/ 

    if line.match /\[end_marker\]/ 
    within_section = false 

    replace_these.each { |line| 
     # Do something clever... 
     line.gsub!(/:(\w+)/, ':\1 was replaced!') 
    } 

    replace_these = Array.new 
    end 

    next if !within_section 

    # Store lines to be replaced for later processing 
    replace_these << line if line.match /\[replace:.*\]/ 
} 

# Make a backup of the original file 
File.move(file, "#{file}.bak") 

# Overwrite the original with the new data 
File.writelines(file, lines) 

Ruby是一個有趣的語言編程中,和一個不錯的除了在你的「工具皮帶」。所以可能是你想看看的東西。

+0

我試圖運行你的示例程序,並且遇到了代碼開始時使用的'requires'問題。當我嘗試運行該程序時,您使用的'ftools'和'extensions/io'都會給我「沒有這樣的文件」異常。使用Ruby 1.9.2p290。 –

+0

好的。在1.9'ftools'已被'fileutils'取代,所以使用它。對於'extensions',只需安裝gem:'gem install extensions'(如果您使用的是'rvm',否則'sudo gem install extensions')。 – Casper

+0

我得到了擴展安裝,我認爲,但現在我得到一個新的錯誤:「未初始化常量對象:: VERSION(名稱錯誤)」我正在查看是否有我的'需要'語句中的某個錯字。 –

相關問題