Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How can I get the position and captured groups from a regex match?

Quick answer

In Python, keep the match object returned by re.search(): use group(0) for the full match, group(1) and later numbers for captures, and start() for the match’s start. In JavaScript, for a non-global regex, match() returns an array with the full match and captures; read its index property for the start. The result shapes differ, so use the language-specific access pattern.

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

I can find text with a regex, but how do I get both where it matched and the parts inside my parentheses?

Geez

Treat the match result as two things: the complete text that matched, and any captured pieces. A pair of parentheses creates a capture you can retrieve separately.

For a concrete example, assume the input is Order: AB-42. and the pattern captures the letters and digits separately from a code made of letters, a hyphen, and digits. The match is AB-42; its captures are AB and 42; its start position is 7.

The way you read those values depends on the language. Python returns a match object from re.search(). JavaScript’s non-global String.prototype.match() returns an array with the whole match and captures, plus an index property for the start position. [S1] [S2]

Follow-up question

What would the Python version look like, including printing each value?

Geez

Use re.search() to look for the pattern, then inspect the match object. Check that a match was found before calling its methods:

import re

text = "Order: AB-42."
m = re.search(r"([A-Z]+)-(\d+)", text)

if m:
    print("full match:", m.group(0))
    print("start:", m.start())
    print("letters:", m.group(1))
    print("digits:", m.group(2))

For this example, the output is:

full match: AB-42
start: 7
letters: AB
digits: 42

group(0) is the whole match; positive group numbers select captures, and groups() gives the captured groups together. Python also provides end() and span() if you need the ending position or both boundaries. [S1] The example shows only the start because that is the position you asked for.

Follow-up question

And how do I do the same thing in JavaScript? Is it safe to use the same indexes?

Geez

With a non-global regex, match() gives an array: element 0 is the complete match, and elements 1 and 2 are the captures in order. The array’s index property gives the zero-based start position in the input. [S2]

const text = "Order: AB-42.";
const m = text.match(/([A-Z]+)-(\d+)/);

if (m) {
  console.log("full match:", m[0]);
  console.log("start:", m.index);
  console.log("letters:", m[1]);
  console.log("digits:", m[2]);
}

That prints the same values as the Python example: full match AB-42, start 7, captures AB and 42. The similar numbers can be confusing: Python uses methods such as group(1) and start(), while JavaScript uses array elements for the match and captures and a property for the start. Don’t treat the two result objects as interchangeable.

Follow-up question

What changes if my JavaScript regex has the global g flag, and what should I check when adapting this?

Geez

For JavaScript, a global regex changes what String.prototype.match() returns: with the g flag, it does not return capture groups. If you need captures while matching globally, use RegExp.prototype.exec() or String.prototype.matchAll() instead. [S2] This guide’s JavaScript snippet deliberately has no g flag so its array contains the captures as shown.

A compact adaptation checklist is:

  1. Identify the language and the matching method.
  2. Keep the actual result returned by the match operation.
  3. Read the whole match and each capture using that language’s result shape.
  4. Read the start position using the language-specific property or method.
  5. If using JavaScript with g, choose a capture-capable global-matching method rather than expecting captures from match().

These result shapes and access methods do not guarantee that a match exists or prescribe a pattern for every input. Test your pattern against representative inputs and handle the no-match case.

A practical checklist

  • Confirm which language and matching method your code uses.

  • Separate the full match from the captures when reading the result.

  • Use the language-specific start-position accessor.

  • In JavaScript, check whether the regex has the g flag before relying on match() for captures.

  • Handle the possibility that the pattern finds no match.

A few more useful answers

In Python, how can I get all the captured groups at once?

Call groups() on a successful Python match object to get its captured groups. Use group(0) separately when you also need the complete match. [S1]

In JavaScript, why are my captures missing from `match()`?

Check whether the regex has the global g flag. With that flag, String.prototype.match() does not return capture groups; use RegExp.prototype.exec() or String.prototype.matchAll() when global matching and captures are needed. [S2]

Does the start position come from the capture or the full match?

The examples retrieve the start of the full match: Python uses start(), and JavaScript’s non-global match() result uses index. Python also provides group-specific positions if you need positions for an individual capture. [S1] [S2]

Sources

References used for this guide.

  1. [S1] Python 3 regular-expression operations: Match objects
    docs.python.org · Checked
  2. [S2] MDN: JavaScript String.prototype.match() results
    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