/^/
MediumValidation6 min read

Credit Card Number Regex

Validates the digit-only format of major credit card numbers by issuer prefix and length, covering Visa, MasterCard, American Express, and Discover.

#credit-card#payments#validation#finance#forms

Regex Pattern

^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$

Pattern Breakdown

Hover over a token to see what it does.

^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$
TokenMeaning
4[0-9]{12}(?:[0-9]{3})?Visa: starts with 4, followed by 12 digits (13 total) or 15 digits (16 total).
5[1-5][0-9]{14}MasterCard: starts with 51-55, followed by 14 more digits (16 total).
3[47][0-9]{13}American Express: starts with 34 or 37, followed by 13 more digits (15 total).
6(?:011|5[0-9]{2})[0-9]{12}Discover: starts with 6011 or 65xx, followed by 12 more digits (16 total).
(?:A non-capturing group, used purely for grouping alternatives without creating a capture.
^Anchors the match to the start of the string.
$Anchors the match to the end of the string.

Detailed Explanation

What it does

This pattern checks whether a string of digits matches the length and issuer-prefix rules of the four most common credit card networks: Visa, MasterCard, American Express, and Discover. Each network has a distinct set of valid starting digits (IIN ranges) and a fixed total number of digits.

Why it works

The top-level alternation tries each issuer's rule in turn. Visa numbers start with 4 and are either 13 or 16 digits total, so `4[0-9]{12}(?:[0-9]{3})?` matches the mandatory 13 digits with an optional 3 more. MasterCard numbers start 51-55 and are always 16 digits, Amex numbers start 34 or 37 and are always 15 digits, and Discover numbers start 6011 or 65xx and are always 16 digits. Anchoring the whole expression ensures the entire string, with no extra characters, fits one of these shapes.

Common use cases

  • Client-side format pre-checks on a payment form before calling a payment processor
  • Detecting which card network a number belongs to for displaying the right card logo
  • Sanitizing and validating digit-only card numbers pasted from a clipboard
  • Basic input filtering before running a full Luhn checksum validation

Edge cases

  • Numbers with spaces or dashes, like 4111 1111 1111 1111, fail because this pattern expects digits only
  • A structurally valid-looking number can still fail the Luhn checksum, which this regex does not compute
  • Newer or less common issuers (JCB, Diners Club, UnionPay) are not covered by these four branches
  • A 13-digit Visa number (an older, now-rare format) is still accepted alongside the standard 16-digit form

Limitations

  • Does not perform a Luhn (mod 10) checksum, so it cannot detect typos that still fit the format
  • Does not cover every card network in existence, only the four most common ones
  • Does not accept common human-readable formatting like spaces or hyphens between groups

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

4111111111111111 4111111111111 5500005555555559

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const cardPattern = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$/;

function isValidCardFormat(number) {
  return cardPattern.test(number);
}

console.log(isValidCardFormat("4111111111111111")); // true

Common Mistakes

Treating a regex format match as proof the card number itself is valid or active.

Fix: Always follow the format check with a Luhn checksum, and ultimately rely on the payment processor's own validation.

Feeding in a human-formatted number with spaces or dashes and expecting it to match.

Fix: Strip non-digit characters first, e.g. `number.replace(/\D/g, "")`, before testing against the pattern.

Assuming this pattern covers every card network a business might accept.

Fix: Add extra alternation branches for networks like JCB, Diners Club, or UnionPay if your use case requires them.

Performance Notes

  • Each alternative branch starts with a distinct leading digit, so the engine can usually pick the right branch without much backtracking.
  • All quantifiers use fixed counts (`{12}`, `{13}`, `{14}`), keeping the total work proportional to the input length.
  • Anchoring the whole pattern avoids wasted work scanning for a valid card number embedded in a longer string.

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes