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 リトル エンディアン エンコーディングからファイルを読み取っています (これは、ファイルが属しているゲームが私に与えているものです)。これが問題でしょうか?それを 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にする必要があります。

EDIT2:

これが私の最初の質問に対する私の解決策です。

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

期待どおりに動作します。助けてくれたTHXたくさん。

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 を介して 1 行でこれを行うことができます。

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

これにより、実際に変更されたファイルがコマンドラインに出力されます。見た目が良く、実際に上書きしたい場合は、sed コマンドにパラメーターとして「-i」を追加します。

編集:OK、あなたは絶対に正しかったです。これはエンコーディングの問題であるため、2バイト文字エンコーディングが文字列の不一致と印刷時のスペースの原因でした。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 に答える