Skip to content
Regex for Credit Card Numbers — Pattern Explained with Examples

Regex for Credit Card Numbers — Pattern Explained with Examples

DodaTech Updated Jun 20, 2026 2 min read

Credit card number validation is a common requirement in e-commerce and payment systems. Different card issuers use distinct prefixes and number lengths. While regex can validate the format and issuer pattern, the Luhn algorithm check is essential for detecting mistyped or fraudulent numbers.

The Pattern

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

Pattern Breakdown

PartMeaning
^4Visa starts with digit 4
5[1-5]Mastercard starts with 51-55
3[47]Amex starts with 34 or 37
`6(?:0115[0-9]{2})`
[0-9]{12}Base PAN length (12 digits for Visa 13-16 variation)
(?:[0-9]{3})?Optional 3 extra digits for Visa 16-digit format
$End-of-string anchor

Matches

  • 4111111111111111 (Visa, 16 digits)
  • 5500000000000004 (Mastercard)
  • 378282246310005 (American Express, 15 digits)
  • 6011111111111117 (Discover)
  • 3530111333300000 (JCB)

Does NOT Match

  • 1234567890123456 (no matching issuer prefix)
  • 4111111111111 (Visa with only 13 digits — pattern needs adjustment)
  • 55000000000000004 (17 digits)
  • text (non-numeric)
  • 0000000000000000 (all zeros, not a real card)

Language Examples

JavaScript

const visaRegex = /^4[0-9]{12}(?:[0-9]{3})?$/;
console.log(visaRegex.test('4111111111111111')); // true
console.log(visaRegex.test('1234567890123456'));  // false

Python

import re
visa_pattern = r'^4[0-9]{12}(?:[0-9]{3})?$'
print(bool(re.match(visa_pattern, '4111111111111111')))  # True
print(bool(re.match(visa_pattern, '1234567890123456')))   # False

Ruby

visa_pattern = /^4[0-9]{12}(?:[0-9]{3})?$/
puts visa_pattern.match?('4111111111111111')  # true
puts visa_pattern.match?('1234567890123456')   # false

Common Pitfalls

  • Regex only validates format and issuer prefix — the Luhn check digit algorithm is required for real validation
  • Issuer prefix ranges change over time (e.g., Mastercard now uses 2-series ranges like 2221-2720)
  • Card number length varies by issuer: Amex is always 15 digits, Visa can be 13, 16, or 19 digits
  • Users often input numbers with spaces or dashes — strip formatting before validation
  • Never store raw credit card numbers (PAN) without proper PCI DSS compliance and encryption

Real-World Use Cases

  • Payment form validation — provide real-time feedback on card type and format before submission
  • BIN (Bank Identification Number) lookup — identify issuer from the first 6 digits for routing decisions
  • Transaction logging — mask and validate card numbers in audit logs while preserving last 4 digits for reference

FAQ

Why do I need the Luhn algorithm in addition to regex?
The Luhn algorithm (mod 10) mathematically verifies that a card number is structurally valid. It catches common data entry errors like transposed digits, which regex alone cannot detect.
How do I handle card numbers with spaces or dashes?
Strip all non-digit characters before validation: number.replace(/[\s-]/g, ''). Then apply the issuer regex and Luhn check on the cleaned string.

Related Patterns

Regex for UUID Regex for Email

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro