Reputation: 45
I need to check if the last character in a string is a digit, and if so, increment it.
I have a directory structure of /u01/app/oracle/...
and that's where it goes off the rails. Sometimes it ends with the version number, sometimes it ends with dbhome_1
(or 2
, or 3
), and sometimes, I have to assume, it will take some other form. If it ends with dbhome_X
, I need to parse that and bump that final digit, if it is a digit.
I use split
to split the directory structure on '/', and use include?
to check if the final element is something like "dbhome". As long as my directory structure ends with dbhome_X
it seems to work. As I was testing, though, I tried a path that ended with dbhome
, and found that my check for the last character being a digit didn't work.
db_home = '/u01/app/oracle/product/11.2.0/dbhome'
if db_home.split('/')[-1].include?('dbhome')
homedir=db_home.split('/')[-1]
if homedir[-1].to_i.is_a? Numeric
homedir=homedir[0...-1]+(homedir[-1].to_i+1).to_s
new_path="/"+db_home.split('/')[1...-1].join("/")+"/"+homedir.to_s
end
else
new_path=db_home+"/dbhome_1"
end
puts new_path
I did not expect the output to be /u01/app/oracle/11.2.0/product/dbhom1
- it seems to have fallen into the if
block that added 1
to the final character.
If I set the initial path to /u01/app/.../dbhome_1
, I get the expected /u01/app/.../dbhome_2
as the output.
Upvotes: 0
Views: 324
Reputation: 160551
This is a starting point if you're running Ruby v2.6+:
fname = 'filename1'
fname[/\d+$/].then { |digits|
fname[/\d+$/] = digits.to_i.next.to_s if digits
}
fname # => "filename2"
And it's safe if the filename doesn't end with a digit:
fname = 'filename'
fname[/\d+$/].then { |digits|
fname[/\d+$/] = digits.to_i.next.to_s if digits
}
fname # => "filename"
I'm not sure if I like doing it that way better than the more traditional way which works with much older Rubies:
digits = fname[/\d+$/]
fname[/\d+$/] = digits.to_i.next.to_s if digits
except for the fact that digits
gets stuck into the variable space after only being used once. There's probably worse things that happen in my code though.
This is taking advantage of String's []
and []=
methods.
Upvotes: 0
Reputation: 110675
'/u01/app/11.2.0/dbhome'.sub(/\d\z/) { |s| s.succ }
#=> "/u01/app/11.2.0/dbhome"
'/u01/app/11.2.0/dbhome9'.sub(/\d\z/) { |s| s.succ }
#=> "/u01/app/11.2.0/dbhome10"
Upvotes: 0
Reputation: 11183
I need to check if the last character in a string is a digit, and if so, increment it.
This is one option:
s = 'string9'
s[-1].then { |last| last.to_i.to_s == last ? [s[0..-2], last.to_i+1].join : s }
#=> "string10"
Upvotes: 0
Reputation: 21
You could use a regular expression to make matching a tad bit easier
if !!(db_home[/.*dbhome.*\z]) ..
Upvotes: 1