0

I have this string in ruby and I'm trying to make a match for sin

"please don't share this: 234-604-142"
"please don't share this: 234-604-1421"

so far I have

\d{3}-\d{3}-\d{3}

but this will also match the second case. Adding a ^ and $ for begins and ends will cause this not to function at all.

To fix this I could do this:

x = "please don't share this: 234-604-1421"
x.split.last ~= /^\d{3}-\d{3}-\d{3}$/

but is there a way to match the sin otherwise?

MikaAK
  • 2,334
  • 6
  • 26
  • 53
  • try `/\b\d{3}-\d{3}-\d{3}\b/` – Hunter McMillen Jun 05 '14 at 22:57
  • Will you *ALWAYS* have phone numbers in that format? Phone numbers change depending on the country, and they're not all in a U.S. format. See "http://stackoverflow.com/questions/123559/a-comprehensive-regex-for-phone-number-validation". – the Tin Man Jun 05 '14 at 23:36
  • This is for a sin card not a phone number if you read the very first line.. – MikaAK Jun 07 '14 at 18:16

1 Answers1

3

Another option worth considering for your rule is

(?<!\d)\d{3}-\d{3}-\d{3}(?!\d)

That way, if for any reason your phone number is followed or preceded by letters, as in

"please don't share this number234-604-142because it's private"

the regex will still work.

Explain Regex

(?<!                     # look behind to see if there is not:
  \d                     #   digits (0-9)
)                        # end of look-behind
\d{3}                    # digits (0-9) (3 times)
-                        # '-'
\d{3}                    # digits (0-9) (3 times)
-                        # '-'
\d{3}                    # digits (0-9) (3 times)
(?!                      # look ahead to see if there is not:
  \d                     #   digits (0-9)
)                        # end of look-ahead
zx81
  • 41,100
  • 9
  • 89
  • 105
  • I like this but I'm a tad confused. So its checking to see if there are not numbers ahead? – MikaAK Jun 05 '14 at 23:02
  • Yes, it checks that after the final three digits, there is not another digit. – zx81 Jun 05 '14 at 23:02
  • I think the goal is to *not* match phone numbers. – Hunter McMillen Jun 05 '14 at 23:03
  • well yeah but the regex is still valid since its for a sin ;) – MikaAK Jun 05 '14 at 23:04
  • Note that if you wanted the same thing at the front of the number, as in `please don't share this number234-604-142because it's private` but not `"please don't share this number3234-604-142because it's private"`, we'd have to use a different strategy because JS doesn't support lookbehind. – zx81 Jun 05 '14 at 23:06
  • ah so i would need that as well what would I use to make that work – MikaAK Jun 05 '14 at 23:09
  • @Snowfiring, `the regex is still valid since its for a sin` ... *sin: an immoral act considered to be a transgression against divine law.* – 7stud Jun 05 '14 at 23:16
  • In that situation, a workaround is to match one extra character in front of the first three digits (or none if we are at the beginning of the line, in m mode): `(?:^|\D)(\d{3}-\d{3}-\d{3})(?!\d)`, and to capture the digits to Group 1, as the parentheses do here. Your match is contained in Group 1. – zx81 Jun 05 '14 at 23:21
  • It's a pleasure. Added sample code for that at the bottom of the answer. – zx81 Jun 05 '14 at 23:24
  • @zx81 It's ruby not javascript =) – hwnd Jun 05 '14 at 23:24
  • Please see updated answer... For some reason I thought it was JS not Ruby (as @hwnd pointed out) so we can use lookbehind at the front, same recipe as the back. Sorry for the confusion. – zx81 Jun 05 '14 at 23:28
  • @hwnd Man you're right, why did I think it was JS!... :) Alright that's easy to fix. – zx81 Jun 05 '14 at 23:29
  • @hwnd What, you mean it can happen to you?... :) :) – zx81 Jun 05 '14 at 23:31