Named Groups in re Module

Regular Expressions Mar 20, 2026

Named Groups in re Module

Named groups ((?P<name>pattern)) are the modern, readable way to capture parts of a match in Python’s re module. Instead of remembering that group 3 is the date, you can give it a meaningful name like year. In data science this makes your code self-documenting, easier to maintain, and perfect for complex log parsing, multi-field extraction, and feature engineering pipelines.

TL;DR — Named Groups

  • (?P<name>pattern) → create a named capturing group
  • Access with match.groupdict() or match.group("name")
  • Backreference with \g<name>
  • Return named columns directly with pandas .str.extract()

1. Basic Named Groups

import re

text = "Order ORD-98765 for $1,250.75 on 2026-03-19"

match = re.search(r"ORD-(?P<order_id>\d+).*?\$(?P<amount>\d+(?:,\d+)?(?:\.\d+)?)", text)

print(match.groupdict())
# {'order_id': '98765', 'amount': '1,250.75'}

2. Real-World Data Science Examples with Pandas

import pandas as pd

# Demo file so this example runs as-is (in your project this is your real log export)
pd.DataFrame({"log": [
    "2026-03-19 ERROR: Payment failed for ORD-12345 amount $1,250.75 Qty: 3 user alice@example.com!!! https://shop.example.com/o/12345 call +1 555-123-4567",
    "2026-03-19 WARNING: Slow response for ORD-98765 amount $87.50 Qty: 1 bob@company.com on 03/19/2026 aaaa",
    "INFO: user logged in ORD-555 amount $12.00 Qty: 2 carol@data.org <b>ok</b>",
]}).to_csv("logs.csv", index=False)

df = pd.read_csv("logs.csv")

# Extract multiple named fields in one pass
df[["date", "order_id", "amount"]] = df["log"].str.extract(
    r"(?P<date>\d{4}-\d{2}-\d{2}).*?ORD-(?P<order_id>\d+).*?\$(?P<amount>\d+(?:,\d+)?(?:\.\d+)?)"
)

# Named groups make the resulting DataFrame self-documenting
print(df[["order_id", "amount", "date"]].head())

3. Named Groups in Substitution (Backreferences)

# Reorder date using named groups
print(re.sub(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})",
             r"\g<day>/\g<month>/\g<year>", "2026-03-19"))

4. Best Practices in 2026

  • Use named groups (?P<name>...) for any pattern with more than 2-3 captures
  • Access results with groupdict() — far more readable than numbered groups
  • Use \\g<name> for backreferences in re.sub()
  • Combine with pandas .str.extract() to get a clean DataFrame with named columns
  • Pre-compile patterns that contain many named groups for maximum performance

When Named Groups Pay Off

A named group (?P<name>...) works like a numbered group but also gets a label. You can read it with m.group("name") or get every named group at once with m.groupdict(). Inside the same pattern, (?P=name) is a named backreference, and in replacements \g<name> inserts the captured text.

In pandas, named groups are especially handy: str.extract uses the group names as column names, so the result is ready to join with other data without renaming.

Names also document the pattern. A reviewer can read (?P<amount>\d+\.\d{2}) and understand its purpose without counting parentheses.

Worked Example: From Log Lines to a Typed DataFrame

We parse order lines into named columns and convert the types in one short chain.

import pandas as pd

lines = pd.Series(["2026-02-01 ORD-17 49.90", "2026-02-02 ORD-18 120.00", "bad line"])
pattern = r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<order_id>ORD-\d+) (?P<amount>\d+\.\d{2})"

df = lines.str.extract(pattern)
df["date"] = pd.to_datetime(df["date"])
df["amount"] = df["amount"].astype(float)
print(df)
print(df.dtypes.astype(str).to_dict())

The columns are named date, order_id and amount straight from the pattern. The bad line becomes a row of missing values instead of a wrong partial match, and after conversion date is datetime64 and amount is float64.

Practical Tips

Pick group names that match the column names you want in the final table, such as order_id rather than oid. Then the extracted DataFrame can be joined or saved without a renaming step, and anyone reading the pattern sees the target columns immediately.

After extraction, count the rows that failed to match with df.isna().all(axis=1).sum(). A sudden rise in that number is the earliest sign that the input format has changed.

Common Mistakes

  • Using the same group name twice in one pattern, which raises an error.
  • Writing \g<name> in a non-raw string or forgetting the g.
  • Leaving amounts as strings after extraction, so sums concatenate text.
  • Dropping rows with missing values without counting how many failed to match.

Quick Summary

  • (?P<name>...) labels a group.
  • str.extract turns names into column names.
  • Use groupdict() for a dictionary of results.
  • Convert types right after extraction.

Conclusion

Named groups turn regular expressions from cryptic numbered captures into self-documenting, maintainable code. In 2026 data science projects they are the recommended way to extract multiple structured fields from logs, reports, and raw text. Use them together with pandas vectorized methods and you’ll write cleaner, faster, and far more readable text-processing pipelines than ever before.

Next steps:

  • Convert one of your current regex patterns that uses numbered groups to named groups and enjoy the improved readability

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices