Find numeric sequence of specific length in string in Ruby

I need to be able to extract a sequence of 8 digits from a given string. The sequence is not in the same place from line to line and can be any 8 digits.

Examples of strings to extract from:

"123 ABCDEF 12345678 GHIJKLMN"
"12345678 ABCD 1234 EFGHIJKL"
"123 4567 12345678"

      

In each of the above lines, I only need 12345678

.

I've already tried regex matching /\d+/

, but if 12345678

any number appears before it doesn't work.

+3


source to share


3 answers


You can do it with the following regex:



r = /
    (?<!\d) # negative lookbehind: cannot match a digit
    \d{8} # match 8 digits
    (?!\d) # negative lookahead: cannot match a digit
    /x

 "12345678 ABCD 1234 EFGHIJKL"[r]
   #=> "12345678"
 "x123456789 ABCD 1234 EFGHIJKL"[r]
   #=> nil

      

+5


source


Try to indicate that you want exactly eight digits:

/(?<!\d)\d{8}(?!\d)/

      



Edit: Add a negative look and feel and a negative look to match exactly the 8 digit sequences. Credit: @CarySwoveland.

+3


source


You can do what you want in two steps:

def find8_1(string)
  index = string =~ /\d{8}/
  return index && !(string[index+8] =~ /\d/) ? string[index,8] : nil 
end

# Some examples
puts "Results with find8_1"
puts find8_1("123 ABCDEF 12345678 GHIJKLMN") # => "12345678" 
puts find8_1("12345678 ABCD 1234 EFGHIJKL")  # => "12345678" 
puts find8_1("123 4567 12345678")            # => "12345678" 
puts find8_1("123 4567 1234567")             # => nil 
puts find8_1("123456789")                    # => nil


def find8_2(string) 
  arr = string.scan(/\d+/) 
  return arr.find { |s| s.size == 8}
end

# Some examples
puts "Results with find8_2"
puts find8_2("123 ABCDEF 12345678 GHIJKLMN") # => "12345678" 
puts find8_2("12345678 ABCD 1234 EFGHIJKL")  # => "12345678" 
puts find8_2("123 4567 12345678")            # => "12345678" 
puts find8_2("123 4567 1234567")             # => nil 
puts find8_2("123456789")                    # => nil

      

Note for this solution, if you used arr.select

instead arr.find

, the method will return an array with the entire substring of 8 digits present in the string.

Thanks to @CarySwoveland for helping me improve my answer.

+3


source







All Articles