我创建了一个哈希来将单词从一个 .po 替换到另一个文件,但我不知道如何编写结束文件



我有 2 个文件,origin.txt 和 end.txt

起源.txt有这样的文字:

msgid "Page not found"
msgstr "Page not found translation"
msgid "Latest Listings"
msgstr "Latest Listings translation"

结束.txt没有翻译

msgid "Page not found"
msgstr ""
msgid "Latest Listings"
msgstr ""

我想从原.txt到结束.txt复制翻译的单词。我决定在 ruby 中创建一个哈希,其中包含来自 origin 的所有单词.txt然后替换 msgstr " 行中"之间的翻译。 这是我当前的代码:

tr = {}
msgidline = ""
msgstrline = ""
f = File.open("origin.txt", "r")
target = open("end.txt", 'r+')
# Create a dictionary 
f.each_line do |line|
if line.start_with?("msgid", "msgstr") && line.start_with?(%Q(msgid "")) == false && line.start_with?(%Q(msgstr "")) == false
if line.start_with?("msgid") == true
msgidline = line.scan(/"([^"]*)"/).join()
elsif line.start_with?("msgstr") == true
msgstrline = line.scan(/"([^"]*)"/).join()
end
end
tr[msgidline] = msgstrline
end
msgidlineReference = ""
target.each_line do |line|
if line.start_with?("msgid", "msgstr") && line.start_with?(%Q(msgid "")) == false
if line.start_with?("msgid") == true
msgidReference = line.scan(/"([^"]*)"/).join()
elsif line.start_with?("msgstr") == true 
msgstrtext = line.scan(/"([^"]*)"/).join() 
line.gsub(msgstrtext, tr[msgidReference])
end
end
end
target.close
f.close

我收到零错误:

translate.rb:29:in `gsub': no implicit conversion of nil into String (TypeError)

我不知道热使 sub 或 gsub 命令工作并替换末尾的单词.txt。这是要走的路?或者你认为有更好的方法吗?

编辑更新:我在扫描结束时添加了".join()。现在零错误消失了。谢谢兰廷森铁轨。 现在我需要在文件中写入或替换,因为它没有改变。你有什么想法吗?

重写以获得更多Rubyishness。

tr = {}
msgid = nil
File.readlines("origin.txt").each do |line|
if (match = line[/^s*msgids*"(.*)"s*$/, 1])
msgid = match
elsif (match = line[/^s*msgstrs*"(.*)"s*$/, 1])
tr[msgid] = match
end
end
lines = File.readlines("end.txt").map do |line|
if (match = line[/^s*msgids*"(.*)"s*$/, 1])
msgid = match
elsif (match = line[/^s*msgstrs*"(.*)"s*$/, 1])
line[Regexp.last_match.begin(1), match.length] = tr[msgid]
end
line
end
File.write("end.txt", lines.join)

请注意,您只需要记住 ID;然后当您遇到 STR 时,您可以同时使用两者。在原始代码中,您最终会得到错误的tr因为您在每行之后将内容放入tr中 - 特别是在 ID 更改之后(但尚未读取关联的 STR)。它们需要成对处理。

scan是矫枉过正,因为它会查找多个实例。每行我们只关注一个事件;String#[]正则表达式非常方便。

在 Ruby 中,典型的是使用 带有open的块,这样我们就可以保证文件句柄在不需要后被关闭。当然,脚本退出时ftarget都会关闭,但它不是很优雅。但是,我们想要行,并且恰好存在一种方法可以打开文件,获取所有行并关闭它 - 完美的工作工具。

虽然我们可以打开文件进行读取和写入,读取它然后截断它并写入新内容,但只需打开一次进行读取和一次写入对程序员来说更容易。

至于行,它们可以包含空格,注释或任何我们不感兴趣的内容;因此,不包含ID或STR的每一行仍然保留,没有更改,而STR行使用String#[]=运算符进行转换,以无缝地插入新内容,准确地插入我们找到旧内容的位置。

方法 scan 返回一个数组,而不是一个字符串,gsub 需要一个字符串作为参数。 例如

如果line = %q[msgid "Page not found"]

line.scan(/"([^"]*)"/)会返回[["Page not found"]]

因此,如下所示的内容至少可以消除该错误。

msgstrtext = line.scan(/"([^"]*)"/) 
unless msgstrtext.empty?
line.gsub(msgstrtext.first.first, tr[msgidReference].to_s)
end

完整的代码,包括文件写入和读取

tr = {}
msgidline = ""
msgstrline = ""
f = File.open("origin.txt", "r")
# Create a dictionary 
f.each_line do |line|
if line.start_with?("msgid", "msgstr") && line.start_with?(%Q(msgid "")) == false && line.start_with?(%Q(msgstr "")) == false
if line.start_with?("msgid") == true
msgidline = line.scan(/"([^"]*)"/).join()
elsif line.start_with?("msgstr") == true
msgstrline = line.scan(/"([^"]*)"/).join()
end
end
tr[msgidline] = msgstrline
end
@msgidlineReference = ""
new_lines = File.readlines("end.txt").map do |line|
if line.start_with?("msgid") == true
@msgidReference = line.scan(/"([^"]*)"/).join
@new_line = line
elsif line.start_with?("msgstr") == true 
msgstrtext = line.scan(/"([^"]*)"/).join
@new_line = %Q[msgstr "#{tr[@msgidReference].to_s}"n]
end
@new_line
end
File.write("end.txt", new_lines.join)

相关内容

最新更新