Sam Grant
Sam Grant

Reputation: 442

Python extract string starting with index up to character

Say I have an incoming string that varies a little:

  1. " 1 |r|=1.2e10 |v|=2.4e10"
  2. " 12 |r|=-2.3e10 |v|=3.5e-04"
  3. "134 |r|= 3.2e10 |v|=4.3e05"

I need to extract the numbers (ie. 1.2e10, 3.5e-04, etc)... so I would like to start at the end of '|r|' and grab all characters up to the ' ' (space) after it. Same for '|v|'

I've been looking for something that would: Extract a substring form a string starting at an index and ending on a specific character... But have not found anything remotely close. Ideas?

NOTE: Added new scenario, which is the one that is causing lots of head-scratching...

Upvotes: 2

Views: 1103

Answers (2)

Aviv Yaniv
Aviv Yaniv

Reputation: 6298

To keep it elegant and generic, let's utilize split:

  1. First, we split by ' ' to tokens
  2. Then we find if it has an equal sign and parse the key-value
import re
sabich = "134 |r|     = 3.2e10 |v|=4.3e05"

parts = sabich.split(' |')
values = {}
for p in parts:
    if '=' in p:
        k, v = p.split('=')
        values[k.replace('|', '').strip()] = v.strip(' ')

# {'r': '3.2e10', 'v': '4.3e05'}
print(values)

This can be converted to the one-liner:

import re
sabich = "134 |r|     = 3.2e10 |v|=4.3e05"

values = {t[0].replace('|', '').strip() :  t[1].strip(' ') for t in [tuple(p.split('=')) for p in sabich.split(' |') if '=' in p]}

# {'|r|': '1.2e10', '|v|': '2.4e10'}
print(values)

Upvotes: 3

RichieV
RichieV

Reputation: 5183

You can solve it with a regular expression.

import re

strings = [
    "  1 |r|=1.2e10 |v|=2.4e10",
    " 12 |r|=-2.3e10 |v|=3.5e-04"
]

out = []
pattern = r'(?P<name>\|[\w]+\|)=(?P<value>-?\d+(?:\.\d*)(?:e-?\d*)?)'
for s in strings:
    out.append(dict(re.findall(pattern, s)))

print(out)

Output

[{'|r|': '1.2e10', '|v|': '2.4e10'}, {'|r|': '-2.3e10', '|v|': '3.5e-04'}]

And if you want to convert the strings to number

out = []
pattern = r'(?P<name>\|[\w]+\|)=(?P<value>-?\d+(?:\.\d*)(?:e-?\d*)?)'
for s in strings:
    # out.append(dict(re.findall(pattern, s)))
    out.append({
        name: float(value)
        for name, value in re.findall(pattern, s)
    })

Output

[{'|r|': 12000000000.0, '|v|': 24000000000.0}, {'|r|': -23000000000.0, '|v|': 0.00035}]

Upvotes: 0

Related Questions