ruby regex finding first two numbers in a string - ruby

If I have a string like
6d7411014f
I want to read the the occurrence of first two integers and put the final number in a variable
Based on above example my variable would contain 67
more examples:
d550dfe10a
variable would be 55
What i've tried is \d but that gives me 6. how do I get the second number?

I'd use scan for this sort of thing:
n = my_string.scan(/\d/)[0,2].join.to_i
You'd have to decide what you want to do if there aren't two numbers though.
For example:
>> '6d7411014f'.scan(/\d/)[0,2].join.to_i
=> 67
>> 'd550dfe10a'.scan(/\d/)[0,2].join.to_i
=> 55
>> 'pancakes'.scan(/\d/)[0,2].join.to_i
=> 0
>> '6 pancakes'.scan(/\d/)[0,2].join.to_i
=> 6
References:
String#scan
Array#[]
Array#join

I really can't answer this exactly in Ruby, but a regex to do it is:
/^\D*(\d)\D*(\d)/
Then you have to concatenate $1 and $2 (or whatever they are called in Ruby).

Building off of sidyll's answer,
string = '6d7411014f'
matched_vals = string.match(/^\D*(\d)\D*(\d)/)
extracted_val = matched_vals[1].to_i * 10 + matched_vals[2].to_i

Related

Find a specific character in a string

I want to find a specific character in a given string of number for example if my input is:
1 4 5 7 9 12
Then for 4 the answer should be 1. My code is as follows:
secarr = second.split(" ")
answer = secarr.index(number) #here number is a variable which gets the character
puts answer
The above method works if I write "4" instead of number or any other specific character but does not work if I write a variable. Is there a method in ruby to do the same?
This is probably your variable number is an Integer, and secarr is an Array of Strings. Try to cast the number to string:
answer = secarr.index(number.to_s)

Generate pseudo random string A-Z, 0-9

How can I generate an n-character pseudo random string containing only A-Z, 0-9 like SecureRandom.base64 without "+", "/", and "="? For example:
(0..n).map {(('1'..'9').to_a + ('A'..'Z').to_a)[rand(36)]}.join
Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
An elegant way to do it in Rails 5 (I don't test it in another Rails versions):
SecureRandom.urlsafe_base64(n)
where n is the number of digits that you want.
ps: SecureRandom uses a array to mount your alphanumeric string, so keep in mind that n should be the amount of digits that you want + 1.
ex: if you want a 8 digit alphanumeric:
SecureRandom.urlsafe_base64(9)
Even brute force is pretty easy:
n = 20
c = [*?A..?Z + *?0..?9]
size = c.size
n.times.map { c[rand(size)] }.join
#=> "IE210UOTDSJDKM67XCG1"
or, without replacement:
c.sample(n).join
#=> "GN5ZC0HFDCO2G5M47VYW"
should that be desired. (I originally had c = [*(?A..?Z)] + [*(?0..?9)], but saw from #sawa's answer that that could be simplified quite a bit.)
To generate a random string from 10 to 20 characters including just from A to Z and numbers, both always:
require 'string_pattern'
puts "10-20:/XN/".gen
You can do simply like below:
[*'A'..'Z', *0..9].sample(10).join
Change the number 10 to any number to change the length of string

Find two numbers in string with Ruby using Regex

I have a string that looks like this:
Results 1 - 10 of 20
How would I find the number 10 and 20 of that sentence using regex in Ruby?
Something like:
first_number, second_number = compute_regex(my_string)...
Thanks
Like so:
first, second = *source.scan(/\d+/)[-2,2]
Explanation
\d+ matches any number
scan finds all matches of its regular expression argument in source
[-2,2] returns the last two numbers in an array: starts at index -2 from end, returns next 2
* splat operator unpacks these two matches into the variables first and second (NOTE: this operator is not necessary, you can remove this, and I like the concept)
Try this:
a = "Results 1 - 10 of 20"
first_number, second_number = a.match(/\w+ (\d) \- (\d+) of (\d+)/)[2..3].map(&:to_i)
The map piece is necessary because the regexp MatchData objects returned are strings.

Ruby String pad zero OPE ID

I'm working with OPE IDs. One file has them with two trailing zeros, eg, [998700, 1001900]. The other file has them with one or two leading zeros for a total length of six, eg, [009987, 010019]. I want to convert every OPE ID (in both files) to an eight-digit string with exactly two leading zeros and however many zeros at the end to get it to be eight digits long.
Try this:
a = [ "00123123", "077934", "93422", "1231234", "12333" ]
a.map { |n| n.gsub(/^0*/, '00').ljust(8, '0') }
=> ["00123123", "00779340", "00934220", "001231234", "00123330"]
If you have your data parsed and stored as strings, it could be done like this, for example.
n = ["998700", "1001900", "009987", "0010019"]
puts n.map { |i|
i =~ /^0*([0-9]+?)0*$/
"00" + $1 + "0" * [0, 6 - $1.length].max
}
Output:
00998700
00100190
00998700
00100190
This example on codepad.
I'm note very sure though, that I got the description exactly right. Please check the comments and I correct in case it's not exactly what you were looking for.
With the help of the answers given by #detunized & #nimblegorilla, I came up with:
"998700"[0..-3].rjust(6, '0').to_sym
to make the first format I described (always with two trailing zeros) equal to the second.

How can I output leading zeros in Ruby?

I'm outputting a set of numbered files from a Ruby script. The numbers come from incrementing a counter, but to make them sort nicely in the directory, I'd like to use leading zeros in the filenames. In other words
file_001...
instead of
file_1
Is there a simple way to add leading zeros when converting a number to a string? (I know I can do "if less than 10.... if less than 100").
Use the % operator with a string:
irb(main):001:0> "%03d" % 5
=> "005"
The left-hand-side is a printf format string, and the right-hand side can be a list of values, so you could do something like:
irb(main):002:0> filename = "%s/%s.%04d.txt" % ["dirname", "filename", 23]
=> "dirname/filename.0023.txt"
Here's a printf format cheat sheet you might find useful in forming your format string. The printf format is originally from the C function printf, but similar formating functions are available in perl, ruby, python, java, php, etc.
If the maximum number of digits in the counter is known (e.g., n = 3 for counters 1..876), you can do
str = "file_" + i.to_s.rjust(n, "0")
Can't you just use string formatting of the value before you concat the filename?
"%03d" % number
Use String#next as the counter.
>> n = "000"
>> 3.times { puts "file_#{n.next!}" }
file_001
file_002
file_003
next is relatively 'clever', meaning you can even go for
>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003
As stated by the other answers, "%03d" % number works pretty well, but it goes against the rubocop ruby style guide:
Favor the use of sprintf and its alias format over the fairly
cryptic String#% method
We can obtain the same result in a more readable way using the following:
format('%03d', number)
filenames = '000'.upto('100').map { |index| "file_#{index}" }
Outputs
[file_000, file_001, file_002, file_003, ..., file_098, file_099, file_100]

Resources