Regex to capture GPA with Python

Viewed 145

I am trying to capture GPA with regex in Python. For example, I want to capture just 3.75 for both lines. The word GPA could be at the beginning or end of 3.75.

GPA 3.75 / 4.0
3.75 / 4.0 GPA

((?:gpa[ :]+)(\d\.?\d{0,2})(?:[/\d\. ]{0,6})?)|((\d\.?\d{0,2})(?:[/\d\. ]{0,6})? ?(?:gpa))

Here is my attempt. It works but I would like to know if there is a way not to repeat the yellow parts. They are exactly the same.

enter image description here

You can see more examples here. Thanks!

1 Answers

You can use

m = re.search(r'(\bgpa[ :]+)?(\d+(?:\.\d+)?)[/\d. ]{0,6}(?(1)| *gpa\b)', text, re.I)
if m:
  print(m.group(2))

See the regex demo.

Details:

  • (\bgpa[ :]+)? - an optional capturing group with ID 1: a whole word gpa (case insensitive search is enabled via re.I) and then one or more spaces or colons
  • (\d+(?:\.\d+)?) - Capturing group 2: one or more digits followed with an optional sequence of a dot and one or more digits
  • [/\d. ]{0,6} - zero to six /, digits, dots or spaces
  • (?(1)| *gpa\b) - If Group 1 matches, match an empty string, else, match zero or more spaces and a whole word gpa.

See a Python demo:

import re
texts = ['GPA 3.75/4.00','GPA 3.75/4.0','GPA 3.75 /4.0','GPA 3.75 / 4.0','GPA 3.7 / 4      aaa','Major GPA: 3.6/4.0','GPA 3.1','GPA 3','some text GPA 3','3.25/4.0 GPA','some text 3.26 / 4.0 GPA','Minor in Art and Technology - 3.5/4.0 GPA aaaa','Minor in Art and Technology - 3.5 / 4.3 GPA aaaa']
rx = re.compile(r'(\bgpa[ :]+)?(\d+(?:\.\d+)?)[/\d. ]{0,6}(?(1)| *gpa\b)', re.I)
for text in texts:
  m = rx.search(text)
  if m:
    print(text, "=>", m.group(2), sep=" ")

This outputs:

GPA 3.75/4.00 => 3.75
GPA 3.75/4.0 => 3.75
GPA 3.75 /4.0 => 3.75
GPA 3.75 / 4.0 => 3.75
GPA 3.7 / 4      aaa => 3.7
Major GPA: 3.6/4.0 => 3.6
GPA 3.1 => 3.1
GPA 3 => 3
some text GPA 3 => 3
3.25/4.0 GPA => 3.25
some text 3.26 / 4.0 GPA => 3.26
Minor in Art and Technology - 3.5/4.0 GPA aaaa => 3.5
Minor in Art and Technology - 3.5 / 4.3 GPA aaaa => 3.5
Related