Advanced

Validating a value

A validation pattern must accept every good value and reject every bad one. Both directions fail quietly, so the rule is written with cases.

What you will see

3

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Check what a rule accepts.

1

Good value.

import re print(bool(re.fullmatch("\d{3}-\d{4}", "415-0192")))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
True
2

Too long.

import re print(bool(re.fullmatch("\d{3}-\d{4}", "4156-0192")))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
False
3

Empty value.

import re print(bool(re.fullmatch("\d+", "")))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
False
4

Rejects counted.

import re cases = ["", "x", "415-01", "415-0192"] bad = [c for c in cases if not re.fullmatch("\d{3}-\d{4}", c)] print(len(bad))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
3

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A validation runs the pattern against the whole value, then the answer is whether the fit covered all of it.
1 take the value
↓
2 run the pinned pattern
↓
3 check full coverage
↓
4 accept or reject
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

import re sets nothing on screen
print(bool(re.fullmatch("\d{3}-\d{4}", "415-0192"))) True
Why this works
Write the rejects

A rule needs the values it must refuse: empty, one char off, extra text. Those cases find bugs a happy path never shows.

One pattern per field

A big pattern that validates a whole line is hard to fix. Validate each field and combine the results.

Examples

Pin both ends

import re
print(bool(re.fullmatch("\d{3}-\d{4}", "415-0192")))

fullmatch means the whole value is the pattern. A search would accept extra text.

Reject a near miss

import re
print(bool(re.fullmatch("\d{3}-\d{4}", "4156-0192")))

The exact count rejects a longer run. A plus would have accepted it.

Allow one separator

import re
print(bool(re.fullmatch("[a-z]+(@[a-z]+)?", "a@b")))

An optional group allows one extra part and no more.

Case rule set

import re
print(bool(re.fullmatch("[A-Z][a-z]*", "Ada")))

A class sets the case per position. A flag would have allowed both.

Empty is checked

import re
print(bool(re.fullmatch("\d+", "")))

A plus rejects empty. A star would accept it, which is often the bug.

Test the bad list

import re
cases = ["", "x", "415-01", "415-0192"]
bad = [c for c in cases if not re.fullmatch("\d{3}-\d{4}", c)]
print(len(bad))

Run the rejects as a list. A rule that passes all of them is wrong.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Pulling fields out
Previous Lesson
Pulling fields out
Next Lesson
Cost of a pattern
Cost of a pattern →