Reputation: 32061
I have the following pattern which I'm trying to use to match credit card expiration dates:
(0[1-9]|1[0-2])\/?(([0-9]{4})|[0-9]{2}$)
and I'm testing on the following strings:
02/13
0213
022013
02/2013
02/203
02/2
02/20322
It should only match the first four strings, and the last 3 should not be a match as they are invalid. However the current pattern is also matching the last string. What am I doing wrong?
Upvotes: 20
Views: 43294
Reputation: 19397
Since we're talking about a credit card expiration date, once you have validated the input date string using one of the fine regex expressions in the other answers, you'll certainly want to confirm that the date is not in the past.
To do so:
YYYYMM
. For example: 201409
201312
201409 ge 201312
.In Perl, ge
is the greater than or equal to string comparison operator. Note that as @Dan Cowell advised, credit cards typically expire on the last day of the expiry month, so it would be inappropriate to use the gt
(greater than) operator.
Alternatively, if your language doesn't support comparing strings in this fashion, convert both strings to integers and instead do an arithmetic comparison.
Upvotes: 3
Reputation: 4435
Move a right paran:
^(0[1-9]|1[0-2])\/?(([0-9]{4}|[0-9]{2})$)
The end anchor wasn't being applied to the [0-9]{4} option, so more numbers were allowed.
Upvotes: 1
Reputation: 784908
You're missing start of line anchor ^
and parenthesis are unmatched.
This should work:
re = /^(0[1-9]|1[0-2])\/?([0-9]{4}|[0-9]{2})$/;
OR using word boundaries:
re = /\b(0[1-9]|1[0-2])\/?([0-9]{4}|[0-9]{2})\b/;
Upvotes: 47