

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Difficulty: 5
click for more info
Not enough gems
Cost: 6 gems
1: Split Delimiter
incomplete
2: Regex
incomplete
3: Extract Links
incomplete
4: Split Images and Links
incomplete
5: Text to TextNodes
incomplete
This lesson's interactive features are locked, please to keep using them
Before we build the next bit, we need to understand a bit about regexes, or "regular expressions". "Regex" for short, is a programming-language-agnostic way of searching for patterns in text.
They're famous for being hard to read, but occasionally, they are the simplest way to solve a problem.
To get really good at using regex, we'd need a full course on the topic. For now, let's just cover the basics. In Python, we can use the re module to work with regex. It has a findall function that will return a list of all the matches in a string. See examples below.
import re
text = "I'm a little teapot, short and stout. Here is my handle, here is my spout."
matches = re.findall(r"teapot", text)
print(matches) # ['teapot']r"teapot" is a regex pattern.
The r tells Python to treat the string as a "raw" string, which means we don't have to use escape sequences for backslashes. Escaping in Python involves using a backslash (\) to ensure special characters are treated as literal characters.
The pattern teapot will match any exact occurrences of the word "teapot" in the input.
text = "My phone number is 555-555-5555 and my friend's number is 555-555-5556"
matches = re.findall(r"\d{3}-\d{3}-\d{4}", text)
print(matches) # ['555-555-5555', '555-555-5556']\d matches any digit
{3} means "exactly three of the preceding character"
- is just a literal - that we want to match
text = "I have a (cat) and a (dog)"
matches = re.findall(r"\((.*?)\)", text)
print(matches) # ['cat', 'dog']\( and \) are escaped parentheses that we want to match
( and ) is a capture group, meaning it groups the matched text, allowing us to reference or extract it separately.
.*? matches any number of characters (except for line terminators) between the parentheses
text = "My email is [email protected] and my friend's email is [email protected]"
matches = re.findall(r"(\w+)@(\w+\.\w+)", text)
print(matches) # [('lane', 'example.com'), ('hunter', 'example.com')]\w matches any word character (alphanumeric characters and underscores)
+ means "one or more of the preceding character"
@ is just a literal @ symbol that we want to match
\. is a literal . that we want to match (The . is a special character in regex, so we escape it with a leading backslash)
Sometimes you need to match something that is NOT preceded by something else. This is where a negative lookbehind comes in handy.
text = "The word cat appears here, but not in concat"
matches = re.findall(r"(?<!con)cat", text)
print(matches) # ['cat'](?<!con)cat is a negative lookbehind that matches "cat" only if it's NOT preceded by "con"
This allows us to match "cat" but not the "cat" in "concat"
The general syntax is (?<!pattern) where pattern is what you don't want to see before your match
I love regexr.com for interactive regex testing, it breaks down each part of the pattern and explains what it does.