The Regex Generator's "Credit Card" Pattern Actually Matches Any 13-Digit Number
Using the regex generator's "credit card" preset seems like it would filter out strings that look like card numbers — but in practice, it only checks digit count and separator shape. Determining whether a number is actually a valid card number requires a checksum verification called the Luhn algorithm, and that algorithm is fundamentally outside what regex can express. Here's why regex can't do this, and, at the code level, exactly what the actual preset does and doesn't catch.
1. What is the Luhn algorithm?
The Luhn algorithm is a checksum method devised in 1954 by IBM's Hans Peter Luhn, and it's used as a "check digit" on the last position of many identification numbers — credit card numbers, IMEI numbers, business registration numbers, and more. The calculation works by starting from the rightmost digit: odd positions are left as-is, even positions are doubled (and if the result exceeds 9, its digits are added together to reduce it to a single digit), and the number is considered valid only if the sum of all digits is a multiple of 10. This catches a substantial share of simple typos or single-digit forgeries, which is why it's widely used in practice as a first-pass validation step.
2. Why regex can't express this calculation
Regex is a language for determining whether a string matches a specific "pattern." Being based on finite automata, it can check the order, repetition, and presence of characters — but an arithmetic operation that multiplies each digit by a different weight (1x or 2x) and sums all the results to compare against a target value simply doesn't exist in regex's grammar. This isn't a missing feature of any particular regex engine — it's a fundamental limitation from computability theory: the theoretical category of "regular languages" itself cannot express "accumulated state" like an arithmetic running sum. In the end, checking a credit card number with regex means, by definition, only checking the format — actual validity has to be handled with separate code (a loop plus arithmetic).
3. modoohub's regex generator's actual "credit card" preset
Checking the code directly, the credit card preset's regex is \b(?:\d[ \-]?){13,16}\b. In plain terms, it's a pattern that repeats "one digit, optionally followed by a space or hyphen" 13 to 16 times. So it checks exactly two things: ① are there 13 to 16 digits, and ② are the only separators between digits spaces or hyphens? There is no Luhn checksum check, and no issuer BIN check (the leading digits that identify the card network — Visa starts with 4, Mastercard with 51–55, etc.) whatsoever.
4. So when is the format check actually useful?
If the context already makes it certain that "this field is a card number" — such as the card number input field on a payment form — a first-pass format check (has the user filled in all the digits, is the digit count right) is still useful. The problem arises when you try to use it to "detect" card numbers within free text. Running this regex against log files or chat content to find card numbers will produce a large number of false positives on 13–16 digit numbers that have nothing to do with cards — order numbers, phone numbers, serial numbers, and the like.
5. If you actually need to validate the checksum
The Luhn checksum can be implemented in just a few lines with a loop: walk the digits from the right, double every second digit and, if the result exceeds 9, sum its digits, then check whether the total is divisible by 10. Regex can only get you as far as "does this look like the right format" — actually determining "is this a valid number" needs this kind of separate arithmetic logic. Treat a pattern built with the regex generator strictly as a first-pass filter; anywhere payment or validation actually matters, be sure to also use dedicated validation logic or a library that includes the Luhn checksum.
Frequently Asked Questions
Q. Does the "credit card" preset accurately find only real card numbers?
No. This pattern (\b(?:\d[ \-]?){13,16}\b) only checks whether there are 13 to 16 digits separated by spaces or hyphens — it performs no Luhn checksum validation and no issuer BIN (leading digit) check at all. Card-unrelated 13-digit numbers will also match this pattern.
Q. Is it really impossible to validate a Luhn checksum with regex alone?
Yes, within standard regex (regular languages) it's impossible. Multiplying each digit by a different weight and accumulating the sum is an arithmetic operation that falls outside what a regular language can express as pattern matching. Validating it requires ordinary programming code with a loop and arithmetic.
Q. When is this kind of format-check regex actually safe to use?
It's useful when the context already makes it certain that a field is a card number — such as a card number input field on a payment form — and you just need a quick format check. Using it to detect card numbers in free text produces a lot of false positives and isn't suitable.
Q. Does the JWT pattern have a similar limitation?
Yes. The JWT preset matches whenever there are three dot-separated segments of 2 or more characters each, so it also matches version strings like "12.34.56" or other arbitrary dot-separated text. A real JWT has each segment Base64URL-encoded JSON, but the preset doesn't check that structure. For accurate JWT structure validation, decode and inspect with the JWT inspector.