Reputation: 16519
Can someone provide me a regex for SSN that matches either
123-45-6789
OR
XXX-XX-XXXX
I currently have ^\d{3}-?\d{2}-?\d{4}$
which matches the first expression, but I need to add the second expression to it as an alternative.
Thanks!
Upvotes: 46
Views: 137059
Reputation: 13327
To strictly answer you question:
^(123-45-6789|XXX-XX-XXXX)$
should work. ;-)
If you read the section "Valid SSNs" on Wikipedia`s SSN article then it becomes clear that a regex for SSN validation is a bit more complicated.
Accordingly a little bit more accurate pure SSN regex would look like this:
^(?!(000|666|9))\d{3}-(?!00)\d{2}-(?!0000)\d{4}$
Upvotes: 64
Reputation: 894
A more generic match would be:
(^[^-]{3}-?[^-]{3}-?[^-]{4}$)
This would match any sequence of characters other than "-" in 3-3-4 char configuration. For example:
my @str = qw/
1adfasdfa
adsfaouaosd90890
111-232-adafd
xXX-232-1234
111-222-4444
$$%-AF#-131@
/;
foreach(@str)
{
print "$_\n" if /^[^-]{3}-?[^-]{3}-?[^-]{4}$/;
}
Upvotes: 1
Reputation: 168755
So you currently have: ^\d{3}-?\d{2}-?\d{4}$
What you need is to allow any of those numeric blocks to be "X"s instead. This is also fairly simple as a regex - just adapt your existing one to have X
instead of \d
in each of the three places it occurs: X{3}-?X{2}-?X{4}
You won't want to be combining a numeric code with and X code, so you just need to allow either one case or the other, so wrap them up in brackets and us a pipe character to specify one or the other, like so:
^((\d{3}-?\d{2}-?\d{4})|(X{3}-?X{2}-?X{4}))$
You'll probably also want to allow upper- or lower-case X. This can be specified using [Xx]
or by making the whole thing case insensitive, using the i
modifier outside the regex.
Upvotes: 5
Reputation: 151136
Then it can be
/^[\dX]{3}-?[\dX]{2}-?[\dX]{4}$/
if you want x
to be valid too, you can add the i
modifier to the end:
/^[\dX]{3}-?[\dX]{2}-?[\dX]{4}$/i
On second thought, the regex above will accept
123-xx-xxxx
as well, so depending on whether you want this form to be accepted or not, you can use your original form "or" the other form:
/^(\d{3}-?\d{2}-?\d{4})|(xxx-xx-xxxx)$/i
Upvotes: 2
Reputation: 43094
(^\d{3}-?\d{2}-?\d{4}$|^XXX-XX-XXXX$)
should do it.
---- EDIT ----
As Joel points out you could also do ^(\d{3}-?\d{2}-?\d{4}|XXX-XX-XXXX)$
which is a little neater.
Upvotes: 42