C.W.K.
Stream
Lesson 12 of 12 · published

Practical — Tags, Quotes, Numbers

~12 min · practical, patterns

Level 0Pattern-Curious
0 XP0/90 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Three real patterns combining everything

You now have quantifiers, character classes, anchors, and groups. Here's how they combine in real code.

HTML/XML tag (loose)

To extract simple tags like <div>, <p class="foo">: <[^>]+>. The negated class avoids the greedy .* trap. (Real HTML parsing still needs a parser — this works for ad-hoc extraction.)

Quoted string

Match anything between double quotes: "[^"]*". The negated class makes it ReDoS-safe and stops at the first closing quote. To handle escaped quotes inside (\"), the pattern grows: "(?:[^"\\]|\\.)*" — "non-quote-non-backslash, OR an escaped anything."

Number (integer or decimal, signed or unsigned)

-?\d+(\.\d+)? matches: optional minus, one or more digits, optional decimal portion. The decimal portion is wrapped in a group with ? to make the entire .\d+ sequence optional, not just the digits.

The quantifier checklist

When writing a real pattern with quantifiers, ask:

  1. Is each piece + (required) or * (optional)?
  2. Are my .* uses justified, or should they be [^X]*?
  3. Are my {n,m} bounds tight (no whitespace inside)?
  4. Did I anchor where appropriate (\b or ^...$)?
  5. Did I test against empty input and very long input?

Five questions. They catch 90% of quantifier bugs.

Code

Three production-ready patterns·python
import re

# Loose HTML tag
re.findall(r'<[^>]+>', '<p>hi</p> <a href="x">link</a>')
# ['<p>', '</p>', '<a href="x">', '</a>']

# Quoted string with escape support
pat = r'"(?:[^"\\]|\\.)*"'
re.findall(pat, '"simple" "with \\"escape\\" inside"')
# ['"simple"', '"with \\"escape\\" inside"']

# Number: signed integer or decimal
for m in re.finditer(r'-?\d+(?:\.\d+)?', 'price -19.95 qty 7 ratio 0.5'):
    print(m.group())
# -19.95
# 7
# 0.5

External links

Exercise

Pick one pattern from your real codebase that uses .* or .+. Rewrite it using a negated class instead. Test on the same input. The new version should match the same things, just faster and safer.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.