Подтвердить что ты не робот

Как совместить символ ИЛИ ничего с помощью регулярного выражения

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

ex1="An example 123-45-6789"
ex2="123.45.6789 some more things"
ex3="123456789 thank you Ruby may I have another"

все должны войти в метод, который возвращает "123-45-6789". В принципе, что-либо (ВКЛЮЧАЯ ничего), кроме числа или буквы, должно возвращать SSN в формате XXX-XX-XXXX. Часть, которая является stumping, является способом регулярных выражений, чтобы идентифицировать, что ничего не может быть.

То, что у меня есть до сих пор в IDENTIFYING my ssn:

def format_ssns(string)
  string.scan(/\d{3}[^0-9a-zA-Z]{1}\d{2}[^0-9a-zA-Z]{1}\d{4}/).to_a
end

Кажется, что работает на все, что я ожидаю, КРОМЕ, когда нет ничего. "123456789" не работает. Могу ли я использовать регулярные выражения в этом случае для выявления недостатка чего-либо?

4b9b3361

Ответ 1

Вы пытались совместить 0 или 1 символ между вашими номерами?

\d{3}[^0-9a-zA-Z]{0,1}\d{2}[^0-9a-zA-Z]{0,1}\d{4}

Ответ 2

Это уже было передано в комментарии, но просто для получения полного ответа...

У вас есть эти инструменты в вашем распоряжении:

  • x соответствует x ровно один раз
  • x{a,b} соответствует x между a и b раза
  • x{a,} соответствует x не менее a раза
  • x{,b} соответствует x до (максимум) b раз
  • x* соответствует x ноль или более раз (то же, что и x{0,})
  • x+ соответствует x один или несколько раз (то же самое, что и x{1,})
  • x? соответствует x ноль или один раз (то же, что и x{0,1})

Итак, вы хотите использовать этот последний, так как он именно то, что вы ищете (ноль или один раз).

/\d{3}[^0-9a-zA-Z]?\d{2}[^0-9a-zA-Z]?\d{4}/

Ответ 3

Ваше текущее регулярное выражение позволит 123-45[6789, не говоря уже обо всех типах символов Юникода и управляющих символов. В крайнем случае:

123
45師6789

считается совпадающим с вашим регулярным выражением.

Вы можете использовать обратную ссылку, чтобы убедиться, что разделитель одинаков.

/\d{3}([.-]?)\d{2}\1\d{4}/

[.-]? будет соответствовать либо ., -, либо ничего (из-за необязательного квантора ?). Что бы ни было согласовано здесь, будет использоваться, чтобы удостовериться, что второй разделитель является одним и тем же с помощью обратной ссылки.

Ответ 4

Whelp... похоже, я только что нашел свой собственный ответ, но любые подсказки для улучшения были бы полезны.

def format_ssns(string)
  string.scan(/\d{3}[^0-9a-zA-Z]{0,1}\d{2}[^0-9a-zA-Z]{1}\d{4}/).to_a
end

Кажется, это трюк.