Rik*_*Rik 1 ruby string increment
我在Ruby脚本中有一个方法,它试图在保存文件之前重命名文件.它看起来像这样:
def increment (path)
if path[-3,2] == "_#"
print " Incremented file with that name already exists, renaming\n"
count = path[-1].chr.to_i + 1
return path.chop! << count.to_s
else
print " A file with that name already exists, renaming\n"
return path << "_#1"
end
end
Run Code Online (Sandbox Code Playgroud)
假设您将3个具有相同名称的文件保存到目录中,我们会说该文件已被调用example.mp3.这个想法是第一个将被保存为example.mp3(因为它不会被if File.exists?("#{file_path}.mp3")脚本中的其他地方捕获),第二个将被保存为example_#1.mp3(因为它被else上述方法的部分捕获)而第三个被保存为example_#2.mp3(因为它被if上述方法所捕获).
我遇到的问题是双重的.
1)if path[-3,2] == "_#"不适用于整数超过一位数的文件(example_#11.mp3例如),因为字符放置是错误的(你需要它,path[-4,2]但那时不能处理3位数字等).
2)我永远不会遇到问题1)因为该方法无法可靠地捕获文件名.目前它将重命名第一个,example_#1.mp3但第二个重命名为同一个东西(导致它覆盖以前保存的文件).
这可能对Stack Overflow来说太模糊了,但我找不到任何能解决增量字符串某个部分的问题.
提前致谢!
编辑/更新:
Wayne的方法似乎在它自己的方法上工作,但是当它作为整个脚本的一部分被包含时 - 它可以递增一个文件一次(从example.mp3到example_#1.mp3),但不能处理example_#1.mp3并将其递增到example_#2.mp3.提供更多上下文 - 当前脚本找到要保存的文件时,将名称传递给Wayne的方法,如下所示:
file_name = increment(image_name)
File.open("images/#{file_name}.jpeg", 'w') do |output|
open(image_url) do |input|
output << input.read
end
end
Run Code Online (Sandbox Code Playgroud)
我已经编辑了Wayne的脚本,所以现在它看起来像这样:
def increment (name)
name = name.gsub(/\s{2,}|(http:\/\/)|(www.)/i, '')
if File.exists?("images/#{name}.jpeg")
_, filename, count, extension = *name.match(/(\A.*?)(?:_#(\d+))?(\.[^.]*)?\Z/)
count = (count || '0').to_i + 1
"#{name}_##{count}#{extension}"
else
return name
end
end
Run Code Online (Sandbox Code Playgroud)
我哪里错了?再次,在此先感谢.
正则表达式将完成:
#!/usr/bin/ruby1.8
def increment(path)
_, filename, count, extension = *path.match(/(\A.*?)(?:_#(\d+))?(\.[^.]*)?\Z/)
count = (count || '0').to_i + 1
"#{filename}_##{count}#{extension}"
end
p increment('example') # => "example_#1"
p increment('example.') # => "example_#1."
p increment('example.mp3') # => "example_#1.mp3"
p increment('example_#1.mp3') # => "example_#2.mp3"
p increment('example_#2.mp3') # => "example_#3.mp3"
Run Code Online (Sandbox Code Playgroud)
这可能与您正在编写的代码无关,但如果您在同一文件中使用此算法可能有多个线程或进程,则在保存之前检查存在时存在竞争条件:两个编写者都可以找到相同的filename未使用并写入.如果这对您很重要,那么以一种失败的模式打开文件(如果它存在),挽救异常.发生异常时,请选择其他名称.大致:
loop do
begin
File.open(filename, File::CREAT | File::EXCL | File::WRONLY) do |file|
file.puts "Your content goes here"
end
break
rescue Errno::EEXIST
filename = increment(filename)
redo
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1808 次 |
| 最近记录: |