Extract values from Regex Group

Question:

I have a problem in which I need to be able to extract values from a string in a list.

I used re in a for loop to match a group pattern from each string in the list and assign it to a variable and print this on a line using the format method.

import re
inventory = ["shoes, 12, 29.99", "shirts, 20, 9.99", "sweatpants, 25, 15.00", "scarves, 13, 7.75"]

for items in inventory:
    pattern = "(?P<product>[a-z]+),s(?P<quantity>[0-9]+),s(?P<price>[0-9]*.[0-9]{2})"
    details = re.match(pattern, items)
    
    product = details.group('product')
    quantity = details.group('quantity')
    price = details.group('price')
    
    print("The store has {} {}, each for {} USD".format(quantity, product, price))

Which yields me the results

The store has 12 shoes, each for 29.99 USD
The store has 20 shirts, each for 9.99 USD
The store has 25 sweatpants, each for 15.00 USD
The store has 13 scarves, each for 7.75 USD

I wanted to ask if it’s possible to use details.groups to extract the values from the tuple and print the desired result or any advice to refine/simplify this?

Asked By: Igor V

||

Answers:

Actually, we can make your solution even more tight with the help of re.split and f strings:

import re

inventory = ["shoes, 12, 29.99", "shirts, 20, 9.99", "sweatpants, 25, 15.00", "scarves, 13, 7.75"]
for inv in inventory:
    product, quantity, price  = re.split(r',s*', inv)
    print(f"The store has {quantity} {product}, each for {price} USD"

This prints:

The store has 12 shoes, each for 29.99 USD
The store has 20 shirts, each for 9.99 USD
The store has 25 sweatpants, each for 15.00 USD
The store has 13 scarves, each for 7.75 USD
Answered By: Tim Biegeleisen

You can use

print("The store has {quantity} {product}, each for {price} USD".format(**details.groupdict()))

Note that placeholders are named the same way as the regex named capturing groups.

The following code:

import re
inventory = ["shoes, 12, 29.99", "shirts, 20, 9.99", "sweatpants, 25, 15.00", "scarves, 13, 7.75"]
pattern = "(?P<product>[a-z]+),s(?P<quantity>[0-9]+),s(?P<price>[0-9]*.[0-9]{2})"

for items in inventory:
    details = re.match(pattern, items)
    print("The store has {quantity} {product}, each for {price} USD".format(**details.groupdict()))

also prints

The store has 12 shoes, each for 29.99 USD
The store has 20 shirts, each for 9.99 USD
The store has 25 sweatpants, each for 15.00 USD
The store has 13 scarves, each for 7.75 USD

Note also that the pattern is defined outside of the for loop, for better performance.

Answered By: Wiktor Stribiżew
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.