Concepts / Common Regex Patterns for Email and Phone Numbers

Common Regex Patterns for Email and Phone Numbers

re.search() returns a match object when a pattern is found, or None when no match exists.

  • Programming
Interactive lab

Try it: Regular expressions: a backtracking matcher

How Python's re module matches a pattern: it tries each start position, matches tokens one by one, lets greedy quantifiers take as much as possible and give it back when the rest fails (lazy ones take as little as possible), tries alternatives in order and records groups.

How it works

  1. search tries start positions 0, 1, 2 …; match tries only position 0; findall collects every non-overlapping match.
  2. Tokens are matched left to right: literals, ., classes like [a-c] and \d, and zero-width anchors ^, \$, \b.
  3. A greedy quantifier (* + ? {m,n}) takes as many repetitions as it can, then backtracks one at a time; a lazy one (*? +? ??) takes as few as possible and grows only when needed.
  4. Alternatives in a | b are tried in order; the first that lets the whole pattern match wins.
  5. Parentheses capture the text their part matched; captures are undone when the matcher backtracks past them.

Default run (63 steps): re.search('(\\w+)@(\\w+)\\.com', 'mail bo@ikb.com now'): try each start position until one matches. … re.search('(\\w+)@(\\w+)\\.com', 'mail bo@ikb.com now') → <re.Match object; span=(5, 15), match='bo@ikb.com'>

Simplified: A subset of re: no flags, lookarounds, backreferences, named groups or possessive quantifiers; pattern and text up to 24 printable ASCII characters. The trace stops after 1900 attempts ("too many steps") where real Python would keep backtracking.

Educational simulation

Loading the simulation…

From Text to Search Result

When a program needs to locate an email-like or phone-like portion of text, the central question is not only whether the text is present. The program may also need to know exactly what was found and where it appeared. Python's re module provides regular-expression tools for this kind of search. Its re.search() function scans a string for a pattern and produces one of two outcomes: a match object when the pattern is found, or None when no match exists.

Key point

A successful search does not return only True or the matched text. It returns a match object containing information about the match.

The Left-to-Right Scan

When you call re.search(pattern, string), Python scans the string from left to right. As soon as it finds text that satisfies the pattern, the search stops and returns a match object describing that first match. If the pattern never appears, the scan finishes without finding a match and re.search() returns None.

re.search()Input stringLeft-to-right scanFirst matchmatch objectreceives pattern and stringcharacters examinedstops at first match
How does re.search() move through a string and stop when the pattern is found?
Worked example

Finding a Pattern Inside a Message

Suppose a message contains ordinary text followed by a portion that satisfies the pattern supplied to re.search(). What happens during the search?

  1. 1
    Begin

    re.search() receives the pattern and the complete string.

  2. 2
    Scan

    Python examines the string from left to right.

  3. 3
    Stop

    When the first matching portion is found, scanning stops.

  4. 4
    Return

    The function returns a match object describing the portion that matched.

Result

The result is a match object rather than a simple Boolean value.

Two Possible Return Values

The result of re.search() determines the next step in your program. If a match exists, the result is a match object and can be inspected. If no match exists, the result is None. None is falsy, so the result can be tested directly in an if condition. The matched object is truthy, allowing the same condition to represent the question: was a match found?

re.search()pattern and stringMatch objectpattern foundNoneno matchInspect matchgroup, start, endSkip match methodsno match datapattern foundpattern absentmethods are availabledo not call match methods
What does re.search() return when the pattern is found or absent, and how should program control respond?

What do you think happens?

A search finds no portion of the string that satisfies its pattern. What does re.search() return?

  • True

  • The unmatched string

  • None

  • An empty match object

Reveal answer
Answer:

None

re.search() returns None when no match exists. Because None is falsy, a conditional test can use that result to choose the no-match path.

Reading Match Details

A match object stores several useful details. The group() method returns the matched text. The start() method returns the index where the match begins, and the end() method returns the index immediately after the final matched character. The original string is also part of the match object's information.

Match objectMatched textgroup()Starting indexstart()Ending indexend()Original stringaccessesaccessesaccessescontains information about
What information can be extracted from a match object after re.search() finds a match?
Worked example

Connecting Indices to the Matched Text

A match object reports a starting index and an ending index for a matched portion of a string. How can you verify the exact characters included?

  1. 1
    Read the start

    Use match.start() to identify the first character position of the match.

  2. 2
    Read the end

    Use match.end() to identify the position immediately after the final matched character.

  3. 3
    Apply a slice

    Use original_string[match.start():match.end()] to select the same range from the original string.

  4. 4
    Compare

    The slice gives the same matched text returned by match.group().

Result

The match indices follow Python's zero-based indexing and slice convention.

Patterns Versus Literal Text

The re module is most useful when the search condition describes a pattern rather than one exact fixed string. The source material identifies examples such as finding any digit, any word character, a repeating pattern, or one of several alternatives. These are situations where a regular expression can express a broader condition. For an exact literal such as From:, using re.search() does not use the distinctive power of regular expressions.

re.search()search operationPatternwhat to findStringwhere to searchSearch resultmatch object or Nonefirst argumentsecond argumentreturns
How do the pattern, source string, and re.search() function work together?
re.search()patternsfind() or infixed textVariable structuredigits, repetition,alternativesExact textFrom:appropriate forappropriate for
When is re.search() more appropriate than a simpler string operation?
SituationSuitable approachFailure result
Search for an exact fixed string such as From:find() or the in operatorfind() returns -1 when absent
Search for a pattern involving digits, word characters, repetition, or alternativesre.search()re.search() returns None when absent

The choice depends on whether the condition is a literal string or a broader pattern.

Debugging Failed Searches

  • Common mistake

    Calling group(), start(), or end() without checking the search result

    What it looks like

    A search finds no match, so its result is None. Calling a match-object method on that result causes an AttributeError.

    Why it fails

    None is not a match object and does not provide the match-object methods.

    Do this instead

    Check whether the result is present before calling group(), start(), or end().

  • Common mistake

    Treating re.search() as if it returns only True or False

    What it looks like

    A condition confirms that a match exists, but the program still needs the matched text or its location.

    Why it fails

    A successful search returns a match object containing more information than a Boolean value.

    Do this instead

    Keep the match object when you need group(), start(), or end().

  • Common mistake

    Expecting re.search() and find() to report failure in the same way

    What it looks like

    A missing literal gives -1 from find(), while a missing regular-expression match gives None from re.search().

    Why it fails

    The two APIs use different failure values.

    Do this instead

    Interpret -1 as find() failure and None as re.search() failure.

  • Common mistake

    Using a regular expression for a simple literal search

    What it looks like

    Searching for the exact text From: with re.search() instead of using find() or in.

    Why it fails

    This does not take advantage of regular-expression pattern matching.

    Do this instead

    Use simpler string methods for exact fixed text.

Best practice

Separate the two questions in your reasoning: first ask whether the result is a match object, and only then ask what text or positions the object contains. This makes None returns a normal branch of control rather than an unexpected error.

Apply the Decision

MEDIUM

For each situation, decide whether re.search(), find(), or in is the better starting point. Then state what result you must check before extracting match details: an exact search for From:, a search for any digit, and a search for a repeating pattern.

Hints
  • Use simpler string methods for an exact fixed string.
  • Use re.search() when the condition describes a pattern.
  • Only a match object has group(), start(), and end().
Worked example

A Reliable Search Routine

Describe the safe reasoning sequence for searching a message for a pattern that might or might not occur.

  1. 1
    Prepare

    Import the re module and identify the pattern and source string.

  2. 2
    Search

    Call re.search(pattern, string).

  3. 3
    Branch

    Treat a match object as the found branch and None as the no-match branch.

  4. 4
    Inspect

    Only on the found branch, use group() for the matched text and start() or end() for its positions.

Result

A safe search routine checks the return value before accessing match-object methods.

Essential Takeaways

  1. 1
    re.search() scans a string from left to right and stops at the first match.
  2. 2
    A found pattern produces a match object; an absent pattern produces None.
  3. 3
    Use group(), start(), and end() to inspect matched text and its positions.
  4. 4
    The start and end values follow Python's zero-based indexing and slicing convention.
  5. 5
    Use re.search() for patterns and find() or in for exact fixed strings.

At a glance

  • re.search() returns a match object when its pattern is found and None otherwise.
  • Python scans from left to right and returns the first matching portion.
  • A match object exposes the matched text with group() and its boundaries with start() and end().
  • Always check for a match before calling match-object methods.
  • Use regular expressions for patterns; use find() or in for simple literal searches.

Related concepts

More concepts starting with C