使用正则表达式匹配模式
使用正则表达式,通过 .str.extract()、.str.contains() 和 .str.match() 提取子字符串并检查模式。
使用正则表达式匹配模式 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Why Regex in Pandas?
Regular expressions (regex) are a language for describing string patterns. In Pandas, the .str accessor exposes regex through contains(), match(), extract(), findall(), and replace(). Regex is the right tool when your patterns are too complex for simple contains/startswith checks — for example, validating email formats, extracting phone numbers from free text, or finding all dollar amounts in a notes column.
import pandas as pd
df = pd.DataFrame({
'text': ['Order #12345 placed', 'No order', 'Ref #67890 paid', 'Refund for #11111']
})
# Find rows that contain an order number (# followed by 5 digits)
has_order = df['text'].str.contains(r'#\d{5}', regex=True)
print(df[has_order])
# text
# 0 Order #12345 placed
# 2 Ref #67890 paid
# 3 Refund for #11111.str.contains() with Regex
.str.contains(pattern) with regex=True (the default) returns a boolean Series that is True wherever the pattern matches anywhere in the string. Use anchors like ^ (start) and $ (end) to restrict where the match occurs. Common uses: filter rows where a field matches a format requirement, like a valid date pattern or a properly formatted code.
import pandas as pd
df = pd.DataFrame({
'code': ['US-001', 'UK-042', 'DE-18', 'FR-', 'us-003']
})
# Valid format: two uppercase letters, hyphen, 3 digits
valid = df['code'].str.contains(r'^[A-Z]{2}-\d{3}$', regex=True)
print(df['code'][valid].tolist())
# ['US-001', 'UK-042'].str.match() for Anchored Matching
.str.match(pattern) checks whether each string starts with the pattern (it is anchored at the beginning). This is the difference from contains() which searches anywhere in the string. Use match() when you only care about the prefix of the string, and fullmatch() when the entire string must match the pattern.
import pandas as pd
df = pd.DataFrame({'id': ['ORD001', 'ORD002', 'RET003', 'ORDXYZ']})
# Match rows whose ID starts with 'ORD' followed by digits
orders = df['id'].str.match(r'ORD\d+')
print(df[orders])
# id
# 0 ORD001
# 1 ORD002
# match() is anchored at start, so 'ORDXYZ' (XYZ not digits) is excluded.str.extract() for Capturing Groups
.str.extract(pattern) uses capturing groups () in the regex pattern to pull out specific parts of matching strings. It returns a DataFrame with one column per capturing group. Only the first match in each string is returned. This is perfect for extracting structured data embedded in free text — like numeric values, dates, or IDs.
import pandas as pd
df = pd.DataFrame({
'notes': ['Shipped on 2024-01-15', 'Delivered on 2024-03-20', 'Pending', 'Shipped on 2024-07-04']
})
# Extract the date (YYYY-MM-DD) from the notes column
dates = df['notes'].str.extract(r'(\d{4}-\d{2}-\d{2})')
df['shipped_date'] = dates[0]
print(df[['notes', 'shipped_date']])
# notes shipped_date
# 0 Shipped on 2024-01-15 2024-01-15
# 1 Delivered on 2024-03-20 2024-03-20
# 2 Pending NaN
# 3 Shipped on 2024-07-04 2024-07-04Named Capturing Groups
You can name capturing groups using (?P<name>...) syntax. When you use named groups with str.extract(), the resulting DataFrame automatically uses those names as column headers — making the output self-documenting without needing to rename columns afterward.
import pandas as pd
df = pd.DataFrame({
'entry': ['Alice (25, Engineer)', 'Bob (30, Manager)', 'Carol (28, Analyst)']
})
# Named capturing groups
extracted = df['entry'].str.extract(
r'(?P<name>\w+) \((?P<age>\d+), (?P<role>\w+)\)'
)
print(extracted)
# name age role
# 0 Alice 25 Engineer
# 1 Bob 30 Manager
# 2 Carol 28 Analyst.str.extractall() for Multiple Matches
.str.extractall(pattern) finds all matches of the pattern in each string (not just the first). It returns a DataFrame with a MultiIndex: the outer level is the original row index and the inner level (match) counts the matches per row. This is useful for extracting all numbers, URLs, or keywords from free-text fields.
import pandas as pd
df = pd.DataFrame({
'text': ['Call 555-1234 or 555-5678', 'Contact 800-9000', 'No numbers']
})
# Extract all phone patterns
all_phones = df['text'].str.extractall(r'(\d{3}-\d{4})')
print(all_phones)
# 0
# match
# 0 0 555-1234
# 1 555-5678
# 1 0 800-9000.str.findall() for a List of Matches
.str.findall(pattern) returns a Series of lists, where each list contains all matches found in that row's string. Unlike extractall(), it does not create a MultiIndex — each row gets a list of matches. This is convenient when you want to keep the results in a flat structure or count matches per row.
import pandas as pd
df = pd.DataFrame({
'text': ['Buy 3 items for $10 each', 'Save $5 on 2 products', 'No deal']
})
# Find all dollar amounts
df['prices'] = df['text'].str.findall(r'\$\d+')
df['price_count'] = df['prices'].str.len()
print(df[['text', 'prices', 'price_count']])
# text prices price_count
# 0 Buy 3 items for $10 each [$10] 1
# 1 Save $5 on 2 products [$5] 1
# 2 No deal [] 0Case-Insensitive Matching with re.IGNORECASE
By default, regex in Pandas is case-sensitive. Pass flags=re.IGNORECASE (or re.I) to make the pattern case-insensitive. This avoids having to write alternation patterns like [Pp][Yy][Tt][Hh][Oo][Nn] when you want to match 'python', 'Python', or 'PYTHON' equally.
import pandas as pd
import re
df = pd.DataFrame({
'skill': ['Python', 'JAVA', 'javascript', 'PyThOn developer', 'SQL']
})
# Case-insensitive search for python
mask = df['skill'].str.contains('python', flags=re.IGNORECASE, regex=True)
print(df[mask])
# skill
# 0 Python
# 3 PyThOn developerValidating Formats with Full Match
.str.fullmatch(pattern) (added in Pandas 1.1) returns True only when the entire string matches the pattern. Unlike contains() which matches a substring, fullmatch is equivalent to anchoring with ^...$. This is the safest way to validate format compliance — email addresses, phone numbers, postal codes, or any field with a strict schema.
import pandas as pd
df = pd.DataFrame({
'email': ['alice@example.com', 'bob_at_work', 'carol@test', 'dave@org.co']
})
# Simple email validation: word@word.word
valid_email = df['email'].str.fullmatch(r'[\w.+-]+@[\w-]+\.[\w.]+')
print(df[valid_email])
# email
# 0 alice@example.com
# 3 dave@org.coReplacing with Regex Backreferences
When using str.replace(pattern, repl, regex=True), the replacement string can include backreferences like r'\1' to refer to the content captured in the first group (). This enables powerful reformatting — for example, switching MM/DD/YYYY to YYYY-MM-DD or wrapping a matched word in HTML tags.
import pandas as pd
df = pd.DataFrame({'phone': ['(555) 123-4567', '(800) 555-0199', '(212) 867-5309']})
# Reformat to 555-123-4567
df['phone_clean'] = df['phone'].str.replace(
r'\((\d{3})\) (\d{3})-(\d{4})',
r'\1-\2-\3',
regex=True
)
print(df)
# phone phone_clean
# 0 (555) 123-4567 555-123-4567
# 1 (800) 555-0199 800-555-0199
# 2 (212) 867-5309 212-867-5309Building a Regex-Based Data Extractor
Here is a practical end-to-end example: extracting product SKU and price from a messy notes column using named groups. This type of extraction is common when importing data from legacy systems where multiple fields were concatenated into one text field.
import pandas as pd
df = pd.DataFrame({
'note': [
'SKU:A001 price:$49.99 in stock',
'SKU:B202 price:$12.50 low stock',
'No SKU available'
]
})
extracted = df['note'].str.extract(
r'SKU:(?P<sku>\w+).*price:\$(?P<price>[\d.]+)'
)
print(extracted)
# sku price
# 0 A001 49.99
# 1 B202 12.50
# 2 NaN NaNQuick Check
Test your understanding of pattern matching with regex in Pandas.
Lesson Recap
In this lesson you learned: str.contains(regex) filters rows by pattern, str.extract() captures the first match into a DataFrame column (use named groups for self-documenting output), str.extractall() finds all matches per row with a MultiIndex, and str.fullmatch() validates that the entire string conforms to a pattern. Next up we combine and clean multiple text columns.
常见问题解答
「使用正则表达式匹配模式」课时是免费的吗?
是的 — 「使用正则表达式匹配模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。
「使用正则表达式匹配模式」这节课中我会学到什么?
使用正则表达式,通过 .str.extract()、.str.contains() 和 .str.match() 提取子字符串并检查模式。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Pandas & NumPy Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「使用正则表达式匹配模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?
能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。