Guides / Regex validation

Updated October 2, 2026 · 9 minute read

Regex validation without false positives

A regex that finds a pattern is not automatically a regex that validates an entire value. These rules make the difference.

Match the whole value

Without anchors, /\d5/ accepts abc12345xyz because it finds a five-digit substring. Validation usually needs start and end anchors.

const postalCode = /^\d{5}$/;
postalCode.test('12345');       // true
postalCode.test('abc12345');    // false

Define what whitespace means

Decide whether leading spaces are invalid or should be normalized. Do not let trimming happen accidentally in one layer but not another.

const value = input.trim();
const username = /^[a-z0-9_]{3,20}$/i;

Avoid .* when the allowed set is known

Broad wildcards accept line breaks and unexpected punctuation, and can create expensive backtracking. Express allowed characters and maximum lengths directly.

// Too broad
/^ID-.*$/

// Bounded and explicit
/^ID-[A-Z0-9]{6,12}$/

Use groups carefully

Alternation has lower precedence than many developers expect. Group alternatives before anchoring them.

// Wrong: starts with cat OR ends with dog
/^cat|dog$/

// Correct: exactly cat or dog
/^(?:cat|dog)$/

Treat email regex as a product decision

There is no short regex that perfectly implements the full email specification. For normal products, check a useful shape, limit length, and verify ownership by sending a message.

const practicalEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

function isAcceptableEmail(value) {
  return value.length <= 254 && practicalEmail.test(value);
}

Build a test matrix before shipping

Every validation rule needs examples that should pass, examples that should fail, and boundary cases. Include empty input, maximum length, Unicode, whitespace, punctuation, and strings that contain a valid substring.

const cases = [
  ['ada_01', true],
  ['ab', false],
  ['ada-01', false],
  [' ada_01 ', false],
  ['a'.repeat(21), false]
];

for (const [value, expected] of cases) {
  console.assert(username.test(value) === expected, value);
}

Use the Regex Tester to inspect every match and capture group before moving the pattern into application code.

Related references