Захват телефона с регулярным выражением в рубине

Я пытаюсь захватить испанские телефонные номера, которые могут иметь следующие формы:

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

Я использую это регулярное выражение в ruby:

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

Проблема заключается в том, что он также фиксирует другие числа в тексте. В частности, я хотел бы захватить все 9 чисел, начиная с 6, которые могут быть разделены пробелами, тире или точками; и не окружены другими номерами (поскольку иногда у меня есть большие ссылки, например, ref: 3453459680934983).

Любая подсказка?

Большое спасибо!

4 ответа

код

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

Выход


Вы можете использовать это регулярное выражение:

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

Рабочая демонстрация

Кстати, если вы хотите совместить последние числа с принудительным исполнением, чтобы начать с 6, вы можете использовать:

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

Рабочая демонстрация


Шаблон, соответствующий этим символам, прост:

/[\d .-]+/

http://rubular.com/r/hSj7okaji3

Вы можете сделать это немного более всеобъемлющим и искать цифры и разделители в определенных положениях:

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

http://rubular.com/r/HkSp8qk0ph

Например:

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"]

Как только у вас есть номера, как правило, вы должны их нормализовать до хранения в базе данных:

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

Как только вы это сделаете, отформатируйте их по мере необходимости, когда будете готовы их отобразить:

pn = "623456789".match(/(?<n1>\d{3})(?<n2>\d{2})(?<n3>\d{2})(?<n4>\d{2})/)
# => #</n4></n3></n2></n1>

(Я использую named capture выше, но это просто для иллюстрации того, как извлекаются значения.)

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

или

pn.captures.join('-') # => "623-45-67-89"


Как насчет этого:

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

licensed under cc by-sa 3.0 with attribution.