2011-07-23 137 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(名称错误)”我正在查看是否有我的'需要'语句中的某个错字。 –

相关问题