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.