gpt4 book ai didi

ruby - 如何在 ruby​​ 中使用正则表达式和 .sub 覆盖 txt 文件中的部分行

转载 作者:太空宇宙 更新时间:2023-11-03 18:03:51 24 4
gpt4 key购买 nike

我在 txt 文件中有以下布局。

[项目] 标签 1:评论 1 |标签 2: foo

我有下面的代码。目标是修改文本中现有行的一部分

def replace_info(item, bar)
return "please create a file first" unless File.exist?('site_info.txt')
IO.foreach('site_info.txt','a+') do |line|
if line.include?(item)
#regex should find the data from the whitespace after the colon all the way to the end.
#this should be equivalent to foo
foo_string = line.scan(/[^"label2: "]*\z/)
line.sub(foo_string, bar)
end
end
end

请指教。也许我的 regrex 已关闭,但 .sub 是正确的,但我无法覆盖 line

最佳答案

小问题:您的正则表达式与您的想法不符。 /[^"label2: "]*\z/ 表示:行尾的任意数量的非 a, b 的字符、el"、空格、冒号或 2(参见 Character classes)。和 scan 返回一个数组,sub 不能使用它。但这并不重要,因为...

小问题:line.sub(foo_string, bar) 什么都不做。它返回一个更改后的字符串,但您没有将它分配给任何东西,它会被丢弃。 line.sub!(foo_string, bar) 会改变 line 本身,但这会导致我们...

大问题:您不能只更改读取行并期望它在文件本身中发生更改。这就像读一本书,认为你可以写出更好的台词,并期待它能改变这本书。更改文本文件中一行的方法是从一个文件中读取并将您读取的内容复制到另一个。如果你在读和写之间换了一行,新写的副本就会不同。最后,您可以将新文件重命名为旧文件(这将删除旧文件并自动将其替换为新文件)。

编辑:这是一些代码。首先,我不喜欢 IO.foreach,因为我喜欢自己控制迭代(而且 IMO,IO.foreach 不像 IO#each_line 那样可读).在正则表达式中,我使用 lookbehind 来查找标签而不将其包含在匹配中,因此我可以只替换值;出于类似的原因,我更改为 \Z 以从匹配中排除换行符。您不应该从函数返回错误消息,这就是异常的用途。我将简单的 include? 更改为 #start_with? 因为当我们不想触发更改时,您的 item 可能会在行的其他地方找到.

class FileNotFoundException < RuntimeError; end

def replace_info(item, bar)
# check if file exists
raise FileNotFoundException unless File.exist?('site_info.txt')

# rewrite the file
File.open('site_info.txt.bak', 'wt') do |w|
File.open('site_info.txt', 'rt') do |r|
r.each_line do |line|
if line.start_with?("[#{item}]")
line.sub!(/(?<=label2: ).*?\Z/, bar)
end
w.write(line)
end
end
end

# replace the old file
File.rename('site_info.txt.bak', 'site_info.txt')
end

replace_info("item", "bar")

关于ruby - 如何在 ruby​​ 中使用正则表达式和 .sub 覆盖 txt 文件中的部分行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54283040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com