1

我对编程完全陌生,并且在过去几周学习了一些 ruby​​ 教程。我需要一个程序来替换大约 600 个文件中的几个单词。目前我被困在使用 sub 和 gsub 来更改我从特定文件中读取的变量中的单词。

My code looks like this:

Dir.glob("items/**/*.dat") do |item_dat_file| 
  puts "working on: " + item_dat_file + " ... "
  puts
  text_full = File.read(item_dat_file)

  puts text_full
  text_full.sub!('[UNIT]', "TESTIT")
  puts text_full

不幸的是,变量 text_full 的两个输出都是相同的,没有任何东西被替换。

 [ U N I T] #=> should be changed
...
 [ / U N I T ]

我正在从 utf-16 Little Endian 编码读取文件(这是文件所属的游戏给我的)。这可能是问题吗?因为在将其读入 ruby​​ 变量后,所有字符之间都会添加空格。Ruby 告诉我 item_dat_file.encoding,该文件是 UTF-8。

非常感谢。

编辑:

我发现了一个关于用 ruby​​ 打开 UTF-16 文件的提示。我更改了代码:

Dir.glob("items/**/*.dat") do |item_dat_file|
  puts "working on: " + item_dat_file + " ... "
  text_full = File.open(item_dat_file, "rb:UTF-16LE:UTF-8").read
  puts text_full.sub("UNIT", "TESTIT")
  puts text_full
end

现在打印的文本很好,没有更多的空格字符。但是,当写回文件时,我该如何扭转呢?最后它应该再次具有 UTF-16。

编辑2:

这是我最初的问题的解决方案。

Dir.glob("items/**/*.dat") do |item_dat_file|
  puts "working on: " + item_dat_file + " ... "
  text_full = File.open(item_dat_file, "r:UTF-16LE:UTF-8").read
  text_full.sub!("UNIT", "TESTIT")
  puts text_full
  File.open(item_dat_file, "w:UTF-16LE").write text_full
end

按预期工作。非常感谢您的帮助。

4

1 回答 1

0

我假设输入/输出在 [UNIT] 中实际上没有空格。如果是这样,您需要将它们添加到要替换的模式中。

sub 和 gsub 之间的区别在于 gsub 将替换整个文本中的所有匹配模式,而 sub 只会做第一个。

这是来自 IRB 的快速测试,显示了差异:

irb(main):013:0> s = '[UNIT]
irb(main):014:0'
irb(main):015:0' blah
irb(main):016:0'
irb(main):017:0' [UNIT];
irb(main):018:0' '
=> "[UNIT]\n\nblah\n\n[UNIT];\n"

irb(main):021:0> print s.sub('[UNIT]', 'TESTIT')
TESTIT

blah

[UNIT];
=> nil

irb(main):022:0> print s.gsub('[UNIT]', 'TESTIT')
TESTIT

blah

TESTIT;
=> nil

编辑:如果您使用的是 Unix/Linux,或者您的系统上有类似 GNU 的工具,您可以通过 find/grep/sed 在一行中执行此操作,如下所示:

find . -print | grep -i "items/.*/*.dat" | xargs sed "s/\[UINT\]/TESTIT/gi"

这实际上会将更改的文件打印到命令行。如果它们看起来不错,并且您想实际覆盖它们,请将“-i”作为参数添加到 sed 命令。

编辑:好的,你是绝对正确的,这是一个编码问题,所以两字节字符编码是导致字符串不匹配和打印时空格的原因。我无法在 OSX 上提取 .adm 文件,所以我下载了一个 mod 并尝试使用其中的 .dat 文件,结果如下:

# encoding: utf-8
Dir.glob("*.dat") do |item_dat_file| 
    puts "working on: " + item_dat_file + " ... "
    fd = File.open(item_dat_file, "rb:UTF-16LE")

    text_full = fd.read().encode("UTF-8")

    puts text_full
    text_full.gsub!("[OBJECT]", "TESTIT")
    puts text_full
end

基本上,您以 UTF-16LE 格式打开文件,读取它,然后将其编码为 UTF-8。像你想要的那样修改它,然后当你必须写回它时,你可以调用:

text_full.encode("UTF-16LE")

并将其写入文件。此示例不处理回写文件,但应该不难弄清楚。

希望这可以帮助。

于 2013-03-12T19:25:03.407 回答