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

Markdown Patterns

~10 min · markdown, rewriting

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

Markdown is line-oriented and partly regex-friendly

Markdown's inline patterns (**bold**, *italic*, `code`, [link](url)) match well with regex. Block patterns (lists, blockquotes, code fences) are line-by-line state. Real Markdown parsers handle all of it correctly.

Bold and italic

Bold:    \*\*([^*]+)\*\*
Italic:  \*([^*]+)\*

Watch the order — if you process bold first, italic patterns won't accidentally consume **.

Inline code

`([^`]+)`

Backticks bracketing non-backtick content. For code that contains backticks, real Markdown uses double backticks (``code with `backticks` inside``) — handle if needed.

Links

\[([^\]]+)\]\(([^)]+)\)

Captures link text in group 1, URL in group 2. Doesn't handle nested brackets or images (![alt](url)) — add !? at the start for that.

Headings

Line-anchored: ^(#{1,6})\s+(.+?)\s*$ with MULTILINE. Captures level (number of #) in group 1, text in group 2.

The right tool: a real parser

For converting Markdown to HTML, processing nested lists, or anything beyond ad-hoc rewrites, use a real parser: Python markdown or mistune, JS marked, Rust pulldown-cmark. Regex is for spot fixes and lightweight transformations.

Code

Markdown rewriting·python
import re

text = '''# Title
This is **bold** and *italic* and `code`.
See [the docs](https://example.com).'''

# Bold to HTML
text = re.sub(r'\*\*([^*]+)\*\*', r'<strong>\1</strong>', text)

# Italic — note: must run AFTER bold or it matches part of bold
text = re.sub(r'(?<!\*)\*([^*]+)\*(?!\*)', r'<em>\1</em>', text)

# Inline code
text = re.sub(r'`([^`]+)`', r'<code>\1</code>', text)

# Links
text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<a href="\2">\1</a>', text)

# Headings (multi-line)
def heading(m):
    level = len(m.group(1))
    return f'<h{level}>{m.group(2)}</h{level}>'

text = re.sub(r'^(#{1,6})\s+(.+?)\s*$', heading, text, flags=re.MULTILINE)

print(text)
# <h1>Title</h1>
# This is <strong>bold</strong> and <em>italic</em> and <code>code</code>.
# See <a href="https://example.com">the docs</a>.

External links

Exercise

Take a Markdown file. Write a regex that finds every link [text](url) and prints the link text and URL in two columns. Run it on a real document. Notice how cleanly regex handles inline patterns when you don't need full Markdown semantics.

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.