Splitting a string by multiple possible delimiters

Viewed 40

I want to parse a str into a list of float values, however I want to be flexible regarding my delimiters. Specifically, I would like to be able to use any of these

s = '3.14; 42.2'  # delimiter is '; '
s = '3.14;42.2'   # delimiter is ';'
s = '3.14, 42.2'  # delimiter is ', '
s = '3.14,42.2'   # delimiter is ','
s = '3.14 42.2'   # delimiter is ' '

I thought about removing all spaces, but this would disable the last version; I tried the re.split()-function by doing re.split('[;, ]', s) which would work using a single character as delimiter but fails otherwise.

I can however do

s.replace('; ', ';').replace(', ', ';').replace(',', ';').replace(' ', ';')
s.split(';')

which works but seems not really like a good practice or useful - especially if I would add even more delimiters in the future. What would be a good approach to do this?

4 Answers

You can use re.split and split on (The [ ] is a space and the brackets are for display only)

[;,] ?|[ ]

The pattern matches

  • [;,] ? Match either ; or , followed by an optional space
  • | or
  • [ ] Match a single space

Regex demo | Python demo

A bit more strict pattern with lookarounds could be asserting a digit on the left using lookarounds.

(?<=\d)(?:[;,] ?| )(?=\d)

The pattern matches:

  • (?<=\d) Positive lookbehind, assert a digit to the left
  • (?: Non capture group for the alternation
    • [;,] ? Match either ; or , followed by an optional space
    • | Or
    • Match a space
  • ) Close non capture group
  • (?=\d) Positive lookahead, assert a digit to the right

Regex demo

Example code

import re

strings = [
    "3.14; 42.2",
    "3.14;42.2",
    "3.14, 42.2",
    "3.14,42.2",
    "3.14 42.2"
]

for s in strings:
    print(re.split(r"[;,] ?| ", s))

Output

['3.14', '42.2']
['3.14', '42.2']
['3.14', '42.2']
['3.14', '42.2']
['3.14', '42.2']

I think you can account for the last space(s) like this:

re.split(r'[;,]\s*', s)

Here \s* will capture the spaces after the separator, if any.

Assuming you would know the delimiter of the input ahead of time, you could write a function that takes your delimiter as an argument, replaces with a space, and splits it:

def split_on_delim(strng, delim):
    return strng.replace(delim, ' ').split()

for example:

>>> s = '3.14; 42.2'
>>> split_on_delim(s, '; ')
['3.14', '42.2']
Related