Finding Substrings in Python

Regular Expressions Mar 19, 2026

Finding Substrings in Python

Finding whether a substring exists inside a larger string — and where it appears — is one of the most frequent text operations in data science. Whether you are searching logs for error codes, extracting keywords from descriptions, validating email domains, or preparing data for Regular Expressions, mastering substring search techniques is essential. In 2026, Python offers simple built-in methods as well as powerful regex-based tools for fast and flexible substring finding.

TL;DR — Key Substring Search Methods

  • substring in string → fastest existence check
  • .find(substring) → returns index or -1
  • .index(substring) → returns index (raises error if missing)
  • .count(substring) → counts occurrences
  • re.search() and re.findall() → regex-powered search

1. Basic Substring Finding with String Methods

text = "Python is great for data science and machine learning"

print("data" in text)                    # True
print("Data".lower() in text.lower())    # case-insensitive check (True)

print(text.find("science"))              # returns index (25)
print(text.index("machine"))             # returns index (raises error if missing)
print(text.count("data"))                # number of occurrences

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 export)
pd.DataFrame({
    "customer_name": ["  alice smith ", "BOB JONES", " carol diaz Inc."],
    "first_name": ["Alice", "Bob", "Carol"],
    "last_name": ["Smith", "Jones", "Diaz"],
    "email": [" Alice@Example.com", "bob@company.org", "carol@data.net "],
    "region": ["N.Y.", "California", "N.Y."],
    "company": ["Acme Inc.", "Globex Inc.", "Initech"],
    "product_code": ["EL-101 ", "BK-202", "#HM-303"],
    "product_category": ["electronics", "books", "home"],
    "date_str": ["2026-03-19", "2025-11-02", "2026-01-15"],
    "description": ["Premium laptop for machine learning and data science",
                    "Data book: data cleaning with Python",
                    "Contact sales@shop.com for premium support"],
    "log": ["2026-03-19 - INFO - login", "2026-03-19 - ERROR - timeout", "2026-03-20 - INFO - logout"],
}).to_csv("customer_data.csv", index=False)

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

# Example 1: Check for keywords in descriptions
df["has_premium"] = df["description"].str.contains("premium", case=False, na=False)

# Example 2: Extract position of specific patterns
df["email_position"] = df["description"].str.find("@")

# Example 3: Count occurrences of a substring
df["keyword_count"] = df["description"].str.count("machine learning")

3. Advanced Substring Finding with Regular Expressions

import re

text = "Order ID: ORD-12345, Amount: $1250.75"

# Find with regex
match = re.search(r"ORD-(\d+)", text)
if match:
    print("Found Order ID:", match.group(1))

# Find all occurrences
all_matches = re.findall(r"\$\d+\.\d{2}", text)
print(all_matches)

4. Best Practices in 2026

  • Use substring in string or .find() for simple existence checks
  • Use pandas .str.contains() for fast vectorized search on DataFrames
  • Switch to re.search() or re.findall() when the pattern is complex
  • Always normalize case (.lower()) before searching when case-insensitivity is needed
  • Keep original columns and create search result columns for traceability

Choosing a Search Method

The in operator answers yes or no and is the fastest choice for simple checks. find returns the position or -1, index returns the position or raises ValueError, and count returns how many non-overlapping matches exist.

All of these are case sensitive. Normalise both the text and the search term with lower() or casefold() for case-insensitive checks. In pandas, .str.contains supports case=False directly.

When the search term varies, such as any word starting with "data", switch to re.search or .str.contains with a pattern.

Worked Example: Flagging Reviews

We flag reviews that mention delivery in any case.

import pandas as pd

reviews = pd.Series(["Fast Delivery!", "Great product", "delivery was late", None])

flag = reviews.str.contains("delivery", case=False, na=False)
print(flag.tolist())

text = "Delivery, delivery, DELIVERY"
print(text.lower().count("delivery"), text.find("x"))

Two reviews mention delivery, and na=False turns the missing review into False instead of NaN. The last line counts three mentions after lowercasing and shows that find returns -1 when nothing is found.

Common Mistakes

  • Using find and forgetting that -1 means not found.
  • Treating -1 as a valid index in slicing.
  • Forgetting na=False in pandas filters.
  • Searching case-sensitive text without normalising.

Quick Summary

  • in checks presence quickly.
  • find returns -1; index raises.
  • count gives the number of matches.
  • Use case=False and na=False in pandas.

Conclusion

Finding substrings is a foundational skill that bridges basic string operations and full Regular Expressions. In 2026 data science projects, combine simple in and .find() methods with pandas .str.contains() for most tasks, and use regex when you need more sophisticated pattern matching. These techniques make your text cleaning, validation, and feature extraction pipelines fast, readable, and professional.

Next steps:

  • Review your current text columns and add substring search features using in, .find(), or regex as appropriate

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