Regex in Python to get text after ":"

Viewed 92

I've been trying different combinations to extract the text after ":".

    materials[3] = 'PE HD Monofilament Yarn CFR India Assessment Main Ports Spot 2-4 Weeks Full Market Range Weekly (Low) : USD/tonne'

    re.match(r'(?<=:+.)(.*)', materials[3])

But I've trying different errors on PyCharm, although the sequence aobe was ok when I tested in https://regexr.com/ and simulated the reading.

The error retrieved from Python is the following:

  re.match(r'(?<=:+.)(.*)', materials[3])
Traceback (most recent call last):
  File "C:\Users\p119124\AppData\Local\Programs\Python\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3343, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-210-556fd124536f>", line 1, in <module>
    re.match(r'(?<=:+.)(.*)', materials[3])
  File "C:\Users\p119124\AppData\Local\Programs\Python\Python37\lib\re.py", line 173, in match
    return _compile(pattern, flags).match(string)
  File "C:\Users\p119124\AppData\Local\Programs\Python\Python37\lib\re.py", line 286, in _compile
    p = sre_compile.compile(pattern, flags)
  File "C:\Users\p119124\AppData\Local\Programs\Python\Python37\lib\sre_compile.py", line 768, in compile
    code = _code(p, flags)
  File "C:\Users\p119124\AppData\Local\Programs\Python\Python37\lib\sre_compile.py", line 607, in _code
    _compile(code, p.data, flags)
  File "C:\Users\p119124\AppData\Local\Programs\Python\Python37\lib\sre_compile.py", line 182, in _compile
    raise error("look-behind requires fixed-width pattern")
re.error: look-behind requires fixed-width pattern 

Could you help me out?

The idea is just to extract the "USD/tonne".

4 Answers

Lookbehind patterns in re must match a fixed length string.

Use a capturing group:

import re
materials = 'PE HD Monofilament Yarn CFR India Assessment Main Ports Spot 2-4 Weeks Full Market Range Weekly (Low) : USD/tonne'
match = re.search(r'.*:\s*(.+)', materials)
if match:
  print(match.group(1))

See Python proof and a regex proof.

Expression explanation

--------------------------------------------------------------------------------
  .*                       any character except \n (0 or more times
                           (matching the most amount possible))
--------------------------------------------------------------------------------
  :                        ':'
--------------------------------------------------------------------------------
  \s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    .+                       any character except \n (1 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
  )                        end of \1

There's no reason to use a regex for this at all. str.split will work fine for such a straightforward use case.

materials[3].split(':')[1].strip()

try this:

print(re.search(r'(\s+?:\s+)(.*)', materials).group(2))

There is no need to use a lookbehind. A very simple solution would be this:

import re
materials = 'PE HD Monofilament Yarn CFR India Assessment Main Ports Spot 2-4 Weeks Full Market Range Weekly (Low) : USD/tonne'
output = re.search(":.*", materials)
print(output.group(0)[2:])
#output: 'USD/tonne'

Or this, if you don't want to slice the string and get it purely with the regex:

output = re.search("(?:: )(.*)", materials)
print(output.group(1))
#output: USD/tonne
Related