Home > database >  Remove only non-leading and non-trailing spaces from a string in Ruby?
Remove only non-leading and non-trailing spaces from a string in Ruby?

Time:07-18

I'm trying to write a Ruby method that will return true only if the input is a valid phone number, which means, among other rules, it can have spaces and/or dashes between the digits, but not before or after the digits.

In a sense, I need a method that does the opposite of String#strip! (remove all spaces except leading and trailing spaces), plus the same for dashes.

I've tried using String#gsub!, but when I try to match a space or a dash between digits, then it replaces the digits as well as the space/dash.

Here's an example of the code I'm using to remove spaces. I figure once I know how to do that, it will be the same story with the dashes.

def valid_phone_number?(number)
  phone_number_pattern = /^0[^0]\d{8}$/

  # remove spaces
  number.gsub!(/\d\s \d/, "")
  
  return number.match?(phone_number_pattern)
end

What happens is if I call the method with the following input: valid_phone_number?(" 09 777 55 888 ") I get false because line 5 transforms the number into " 0788 ", i.e. it gets rid of the digits around the spaces as well as the spaces. What I want it to do is just to get rid of the inner spaces, so as to produce " 0977755888 ".

I've tried number.gsub!(/\d(\s )\d/, "") and number.gsub!(/\d(\s )\d/) { |match| "" } to no avail.

Thank you!!

CodePudding user response:

To remove spaces & hyphen inbetween digits, try:

(?:\d |\G(?!^)\d )\K[- ] (?=\d)

See an online regex demo


  • (?: - Open non-capture group;
    • d - Match 1 digits;
    • | - Or;
    • \G(?!^)\d - Assert position at end of previous match but (negate start-line) with following 1 digits;
    • )\K - Close non-capture group and reset matching point;
  • [- ] - Match 1 space/hyphen;
  • (?=\d) - Assert position is followed by digits.

p " 09 777 55 888  ".gsub(/(?:\d |\G(?!^)\d )\K[- ] (?=\d)/, '')

Prints: " 0977755888 "

CodePudding user response:

If you want to return a boolean, you might for example use a pattern that accepts leading and trailing spaces, and matches 10 digits (as in your example data) where there can be optional spaces or hyphens in between.

^ *\d(?:[ -]?\d){9} *$

For example

def valid_phone_number?(number)
  phone_number_pattern = /^ *\d(?:[ -]*\d){9} *$/
  return number.match?(phone_number_pattern)
end

See a Ruby demo and a regex demo.

  • Related