Regular expression - Reading until the first encounter of colon (:) and ignoring the rest of the line and the number part in the beginning

Viewed 54

This is the line

18. Deutsche Post Brand Value: $3,749 million Headquarter City: Bonn Category: Logistics Year Formed: 1947

Desired result is : Deutsche Post Brand Value

With .+?(?=:), I am getting 18. Deutsche Post Brand Value.

But I don't want 18. in it and rest of the line should be ignored as well

any suggestions?

3 Answers

Instead of using a regex, just split your string on known characters

in this case once at the first : after your desired block, then and again at the first space after 18.

In Python, this could look like

>>> test_string = "18. Deutsche Post Brand Value: $3,749 million Headquarter City: Bonn Category: Logistics Year Formed: 1947"
>>> test_string.split(':')  # show splitting
['18. Deutsche Post Brand Value', ' $3,749 million Headquarter City', ' Bonn Category', ' Logistics Year Formed', ' 1947']
>>>
>>> test_string.split(':')[0].split(' ', 1)[1]
'Deutsche Post Brand Value'

If you must use a regex, you could use a capture group to only match a certain block - example again in Python

>>> import re
>>> re.match(r"\d+\.\s*([^:]+)", test_string).groups()
('Deutsche Post Brand Value',)

this works by first matching \d+ N numbers \. literal period \s* any number of whitespace chars .. then () for a capture group with [^:]+ match all the values to the next :

different regex engines will have some way to refer to this group (often \1) or can be directly asked for it (.groups() or .group(1) for Python)

relevant xkcd: xkcd 1171

Use either if supported:

^\d+\.\s*\K[^:]+
(?<=^\d+\.\s+)[^:]+

See proof #1 and proof #2.

Explanation

--------------------------------------------------------------------------------
  (?<=                     look behind to see if there is:
--------------------------------------------------------------------------------
    ^                        the beginning of the string
--------------------------------------------------------------------------------
    \d+                      digits (0-9) (1 or more times (matching
                             the most amount possible))
--------------------------------------------------------------------------------
    \.                       '.'
--------------------------------------------------------------------------------
    \s+                      whitespace (\n, \r, \t, \f, and " ") (1
                             or more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of look-behind
--------------------------------------------------------------------------------
  [^:]+                    any character except: ':' (1 or more times
                           (matching the most amount possible))

I used regex101 to figure out \d*\. *(.*): and have the options set to Ungreedy /U.
You have to pick your wanted value out of Group 1.

\d* means any number of figures \. is a period is the space (*) is any characters up to : the colon.

Related