Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How do Python and JavaScript regexes differ when finding multiple matches?

Quick answer

Python’s re.findall() returns all non-overlapping matches by default. JavaScript’s text.match() returns only the first match unless the regular expression has the g flag; with g, it returns all complete matches. For a pattern without capture groups, both can return a list or array of matched strings. Capture groups change Python’s findall() results, while global JavaScript match() omits capture groups. [S1] [S2]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

I’m checking a string for every word-like match. Why does my Python code return several matches, but my JavaScript version seems to return only one?

Geez

The usual difference is that Python’s re.findall() searches for all non-overlapping matches, while JavaScript’s String.prototype.match() finds only the first match unless its regular expression has the g flag. [S1] [S2]

For example, both snippets below use a pattern with no capture groups, so the results are the complete matched strings.

Python:

import re

text = "red blue red"
result = re.findall(r"\w+", text)
print(result)
# ['red', 'blue', 'red']

JavaScript:

const text = "red blue red";
const result = text.match(/\w+/g);
console.log(result);
// ["red", "blue", "red"]

In JavaScript, removing g changes this example to return just the first match, "red", rather than the array of all matches. [S2]

Follow-up question

What does the g flag actually change about the JavaScript result? Does it still include groups I put in parentheses?

Geez

For text.match(regex), g switches the result from the first match and its capture groups to an array of all complete matches. With g, capture groups are not included in that result. Without g, match() returns the first complete match along with its capture-group values. If there is no match, match() returns null. [S2]

So if you want every complete match, /.../g is the key. If you need capture-group values for every match, don’t assume text.match(/.../g) will provide them: matchAll() and RegExp.prototype.exec() are alternatives for getting capture groups across global matches. [S2] The exact shape you need depends on whether you want whole matches, captured portions, or both.

Follow-up question

Is Python’s findall() result always a list of whole matching strings? I sometimes use parentheses to pull out part of a match.

Geez

No. In Python, the number of capturing groups affects what re.findall() returns: no groups gives the complete matched strings; one group gives that group’s strings; multiple groups give tuples of group values. [S1]

For instance, using the text "id=7 id=12" and pattern r"id=(\d+)", findall() returns ['7', '12'], not ['id=7', 'id=12'], because the parentheses capture just the digits. That is useful when you want the captured part, but it can surprise you if you expected complete matches. [S1]

If you need match objects and details such as positions, Python’s re.finditer() is an alternative. [S1]

Follow-up question

Can you give me a quick way to choose between them, and a small example I can adapt when checking results in both languages?

Geez

Start by deciding what you need back: every complete match, captured values, or match objects with additional details. Then check the language-specific result rules rather than expecting the two APIs to behave identically.

For the same simple task—collecting each word-like match from "red blue red"—use Python’s re.findall(r"\w+", text) and JavaScript’s text.match(/\w+/g). Both produce three complete matches in this example. [S1] [S2]

Before adapting that pattern, try a string with repeated matches and one with no matches. Check whether your pattern contains capturing parentheses: they change Python’s findall() output, and JavaScript’s global match() does not include capture groups. [S1] [S2] For Python match positions or details, consider finditer(); for JavaScript capture groups across global matches, consider matchAll() or exec(). [S1] [S2]

These examples cover the documented interfaces described here; they do not establish that every regular-expression feature or engine behaves the same across the two languages.

A practical checklist

  • Decide whether you need complete matches, captured text, or match details such as positions.

  • In JavaScript, add the g flag when using text.match() to collect all complete matches.

  • In Python, check whether capturing groups change findall() from full matches to captured values or tuples.

  • Try the pattern on text with several matches and on text with no matches.

  • Choose Python finditer() or JavaScript matchAll()/exec() when their match-object or capture-group behavior fits your task.

A few more useful answers

Does Python `findall()` return overlapping matches?

No. It returns all non-overlapping matches. [S1] The cited reference excerpt does not specify a solution for finding overlaps.

What does JavaScript `match()` return when nothing matches?

It returns null. [S2] Check for that before treating the result as an array.

Which Python option helps when I need match positions?

Python’s re.finditer() yields match objects and is useful when you need positions or match details. [S1]

Sources

References used for this guide.

  1. [S1] Python 3.15.2 re — Regular expression operations
    docs.python.org · Checked
  2. [S2] String.prototype.match() — JavaScript | MDN
    developer.mozilla.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work