3

I'm trying to capture spanish phone numbers that can have these forms:

  • 123456789
  • 123 45 67 89
  • 123.45.67.89
  • 123-45-67-89

I'm using this regular expression in ruby:

text.match(/([6][0-9]+\s?\-?\.?[0-9]*\s?\-?\.?[0-9]*\s?\-?\.?[0-9]*)/)

The problem is that it also captures other numbers in the text. Specifically I'd like to capture all 9 numbers starting by 6 that can be separated by white spaces, dashes, or dots; and not surrounded by other numbers (as sometimes I have big references like ref:3453459680934983).

Any clue?

Lots of thanks!

Nick Veys
  • 23,458
  • 4
  • 47
  • 64

4 Answers4

0

You can use this regex:

^\d{3}(?:(?:[ \.\-]?)\d{2}){3}$

Working demo

enter image description here

By the way, if you want to match the last numbers an enforce to start by 6 you can use:

6\d{2}(?:(?:[ \.\-]?)\d{2}){3}$

Working demo

Federico Piazza
  • 30,085
  • 15
  • 87
  • 123
0

How about this:

text.match(/^[0-9]{3}\s*[\-\.]?(?:[0-9]{2}\s*[\-\.]?){3}$/)

celeritas
  • 2,191
  • 1
  • 17
  • 28
0

Code

^6(\d{8}|(\d{2}((\s|\.|-)\d{2}){3}))$

Output

enter image description here

030
  • 10,842
  • 12
  • 78
  • 123
  • 1
    I changed it a bit, so it can be surrounded by other digits and add two more cases, but this syntax helped me a lot. Thanks! My end solution: /6(\d{8}|(\d{2}((\s|\.|-)\d{2}){3})|(\d{2}(\s|\.|-)\d{6})|\d{2}((\s|\.|-)\d{3}){2})/ – Alberto Alcaraz Aug 05 '14 at 21:01
0

The pattern to match those characters is easy:

/[\d .-]+/

http://rubular.com/r/hSj7okaji3

You can make it a little more comprehensive and look for digits and separators in certain positions:

/6(?:\d{8}|\d{2}[ .-](?:\d{2}[ .-]){2}\d{2})/

http://rubular.com/r/HkSp8qk0ph

For instance:

strings = [
  'foo 623456789 bar',
  'foo 123456789 bar',
  'foo 623 45 67 89 bar',
  'foo 123 45 67 89 bar',
  'foo 623.45.67.89 bar',
  'foo 123.45.67.89 bar',
  'foo 623-45-67-89 bar',
  'foo 123-45-67-89 bar',
]

found_pns = strings.select{ |s| s[/6(?:\d{8}|\d{2}[ .-](?:\d{2}[ .-]){2}\d{2})/] }
# => ["foo 623456789 bar",
#     "foo 623 45 67 89 bar",
#     "foo 623.45.67.89 bar",
#     "foo 623-45-67-89 bar"]

Once you have the numbers, typically you should normalize them prior to storing in a database:

found_pns.map{ |s| s[/6(?:\d{8}|\d{2}[ .-](?:\d{2}[ .-]){2}\d{2})/].tr(' .-', '') }
# => ["623456789", "623456789", "623456789", "623456789"]

Once you've done that, then you format them as needed when you get ready to display them:

pn = "623456789".match(/(?<n1>\d{3})(?<n2>\d{2})(?<n3>\d{2})(?<n4>\d{2})/)
# => #<MatchData "623456789" n1:"623" n2:"45" n3:"67" n4:"89">

(I'm using named captures above, but that's just to illustrate how the values are retrieved.)

"%s-%s-%s-%s" % [*pn.captures] # => "623-45-67-89"

or:

pn.captures.join('-') # => "623-45-67-89"
the Tin Man
  • 158,662
  • 42
  • 215
  • 303