0Pricing
Pandas & NumPy Academy · Урок

Сопоставление с шаблонами регулярных выражений

Извлекайте подстроки и проверяйте шаблоны с помощью .str.extract(), .str.contains() и .str.match(), используя регулярные выражения.

«Сопоставление с шаблонами регулярных выражений» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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-04

Named 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      []            0

Case-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 developer

Validating 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.co

Replacing 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-5309

Building 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    NaN

Quick 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.

Часто задаваемые вопросы

Урок «Сопоставление с шаблонами регулярных выражений» бесплатный?

Да — полный текст урока «Сопоставление с шаблонами регулярных выражений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Чему я научусь в уроке «Сопоставление с шаблонами регулярных выражений»?

Извлекайте подстроки и проверяйте шаблоны с помощью .str.extract(), .str.contains() и .str.match(), используя регулярные выражения. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?

Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Сопоставление с шаблонами регулярных выражений»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?

Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Аксессор .str
  2. Разделение и замена строк
  3. Сопоставление с шаблонами регулярных выражений
  4. Объединение и очистка текстовых столбцов
← Назад к Pandas & NumPy Academy