查找和替换文本文件目录中的单词

时间:2011-07-23 03:56:57

标签: programming-languages replace

我正处于为独立游戏开发模式的最后阶段Dwarf Fortress。 mod工作顺序之前需要做的最后一件事是通过并改变Dwarf Fortress RAWs - 大约二十几个文本文件,其中包含有关填充游戏的数百个生物的信息。

从技术角度来看,这相当于通过文本文件目录,并基本上执行“查找和替换”操作来改变每一行。

我的大部分编程经验都是面向对象的语言 - C#和Java,以及使用Assembler和C的一些经验。但是,这些语言似乎都不适合这类任务。

本来是一个非常简单的替代品的一个问题是,由于Dwarf Fortress RAWs的编写方式,我不知道是否需要更换线直到文本文件的下方。以下是一个简短的示例场景。

[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:Y]替换包含[BODY_DETAIL_PLAN:Z]的两行,其中Y根据需要改变关于X的读取值。

我可以保证两件事:

  • 大多数一条[MULTIPLY_VALUE:X]行将出现在[CREATURE:A]和[CREATURE:B]或[CREATURE:Z]和文件末尾之间。
  • 如果[BODY_DETAIL_PLAN:Z]行存在于该生物上,[MULTIPLY_VALUE:X]行将始终

根据我的编码经验,我最接近可行的想法是编写一个C程序来读取文件,使用指针“保存”读取行的位置并在文件读取器检测到时更改它们新RAW的开始。

然而,这让我感到不雅,并且遇到了我没有在C(或任何语言)中实现查找/替换功能的经验。

是否有一些更简单的方法来完成手动浏览每个文本文件的单调任务?我完全愿意学习一种新的编程语言,但我不知道哪种语言最容易处理这种情况。

建议?

2 个答案:

答案 0 :(得分: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是一种有趣的编程语言,并且是“工具带”中的一个很好的补充。所以可能是你想看的东西。

答案 1 :(得分:0)

使用http://www.harddisksearch.com/ ..

将是小菜一碟。