Concepts / Data Validation with Regular Expressions

Data Validation with Regular Expressions

Parentheses in regular expressions mark the portion of a match that findall() should extract and return.

  • Programming

Matching Versus Keeping

A regular expression can recognize more text than you ultimately want to keep. Parentheses solve this problem by marking the specific portion of a successful match that findall() should extract and return. The surrounding pattern still has to match, but the returned result can be only the text inside the parentheses.

X-:42full match42captured substringfindall() returns the group
What is the difference between the entire text matched by a regular expression and the smaller portion returned by a capturing group?
Key point

Parentheses do not change which text the pattern matches. They change which part of that match findall() returns.

Tracing findall() Results

What do you think happens?

A pattern matches the text X-:42. If the number is enclosed in parentheses, what will findall() return?

  • The full text X-:42

  • Only the text 42

  • An empty list

  • A number with integer type

Reveal answer
Answer:

Only the text 42

The full pattern must match, but the parentheses identify 42 as the portion to extract. The extracted result is still a string.

X-:42input textpatternno parenthesesX-:42list of full matchespatternnumber in parentheses42list of captured stringsmatchfindall()matchfindall()
How does findall() change its output when a regular expression contains a capturing group?

Without parentheses, findall() returns the entire substring that matches the pattern. With one capturing group, findall() returns a list containing the strings captured by that group. Therefore, two patterns can match the same text while producing different findall() results.

Parentheses as Capture Boundaries

X-:must match(capture startsnumbercaptured portion)capture endsfollowed bycontainsends at
Which characters in the matched text are selected by the parentheses?

A capturing group is the part of a regular expression enclosed in parentheses. Text outside the group remains important because it must match for the overall pattern to succeed. However, findall() returns only the text represented by the group. The location of the parentheses in the pattern therefore determines which portion is extracted.

Worked example

Extracting a Number From a Marked Line

Consider a line with the form X-:42 and a pattern whose number portion is enclosed in parentheses. What does findall() return?

  1. 1
    Match the required structure

    The line must contain the expected X- prefix, colon, and number. The pattern outside the parentheses participates in this match.

  2. 2
    Identify the captured portion

    The parentheses surround the number, so the number is the portion selected for extraction.

  3. 3
    Read the findall() result

    Because there is one capturing group, findall() returns a list of strings containing the captured number rather than the complete line.

Result

The result contains the extracted number as a string, not as an integer.

Multiple Captured Values

A pattern can contain more than one set of parentheses. In that case, findall() returns a list of tuples. Each tuple contains the captured values in the order in which the groups appear in the pattern.

Worked example

Keeping Two Parts of One Match

Suppose a line contains two portions that a pattern captures with two sets of parentheses. What shape should you expect from findall()?

  1. 1
    Match the complete line structure

    All required text, including the parts outside the parentheses, must match for the pattern to succeed.

  2. 2
    Collect the first group

    The first parenthesized portion becomes the first value in the result tuple.

  3. 3
    Collect the second group

    The second parenthesized portion becomes the second value in the same result tuple.

Result

findall() returns a list of tuples, with captured values ordered by their groups in the pattern.

Pattern structurefindall() result shapeReturned content
No capturing groupListEntire matched substrings
One capturing groupList of stringsOnly the captured substrings
Multiple capturing groupsList of tuplesCaptured substrings in group order

The number of capturing groups changes both the content and structure of findall() results.

Converting Extracted Values

Every value extracted by findall() is a string, even when the characters look like a number. If later work requires arithmetic or comparisons using numeric values, convert the extracted strings explicitly to an appropriate type such as int or float.

Extracted contentInitial result typePossible later type
42StringInteger
3.5StringFloat

The extracted text begins as a string and may need conversion before numeric use.

Safe Result Handling

  • Common mistake

    Treating the full match as the extracted value

    What it looks like

    Expecting findall() to return X-:42 when the number is enclosed in parentheses

    Why it fails

    With a capturing group, findall() returns only the portion inside the parentheses.

    Do this instead

    Identify which part of the pattern is enclosed in parentheses and use that as the expected extracted result.

  • Common mistake

    Assuming an extracted number already has numeric type

    What it looks like

    Using a captured value as though it were already an integer or float

    Why it fails

    findall() always returns extracted values as strings.

    Do this instead

    Convert the string explicitly when arithmetic or numeric comparison is needed.

  • Common mistake

    Accessing a result before checking whether a match occurred

    What it looks like

    Reading an element from the result when the input line does not match the pattern

    Why it fails

    For a nonmatching line, findall() returns an empty list.

    Do this instead

    Verify that the returned list is non-empty before accessing one of its elements.

  • Common mistake

    Expecting the same result shape for every number of groups

    What it looks like

    Treating results from multiple capturing groups as a simple list of strings

    Why it fails

    With multiple groups, findall() returns a list of tuples.

    Do this instead

    Use the number of capturing groups to predict the structure of the result.

Edge case

When an input line does not match the pattern, findall() returns an empty list. A condition that checks whether the list contains at least one result prevents the program from trying to access a value that is not present.

Practice and Review

MEDIUM

For each situation, predict the result shape before writing any processing logic: a pattern with no parentheses, a pattern with one capturing group around the number, and a pattern with two capturing groups. Then decide which extracted values would need conversion before numeric use.

Hints
  • Ask whether findall() should return the complete match or only a captured portion.
  • Count the sets of parentheses in the pattern.
  • Remember that extracted values begin as strings.
  • Consider what happens if no input text matches.
  1. 1
    Parentheses define capturing groups in a regular expression. The complete pattern still controls whether a line matches, but findall() returns only the text inside the groups. One group produces a list of strings, while multiple groups produce a list of tuples. Extracted values are strings and may require conversion to int or float. When a line does not match, findall() returns an empty list, so check the result before accessing an element.

Key Takeaways

  • A regular expression can match a complete structure while a capturing group selects only the portion to extract.
  • findall() returns full matches without capturing groups and captured substrings when groups are present.
  • One capturing group produces a list of strings; multiple groups produce a list of tuples.
  • Extracted values are always strings and must be converted when another type is needed.
  • Check for a non-empty result before accessing extracted values.

Related concepts

More concepts starting with D