Split string without losing delimiter (and its count)

Viewed 172

I'm trying to split a string like below on spaces:

string = "This            is a                      test."

# desired output
# ['This', '            ', 'is', ' ', 'a', '                      ', 'test.']

# actual output, which does make sense
result = string.split()
# ['This', 'is', 'a', 'test.']

There's also re.split which keeps the delimiter, but not in the way I hoped:

import re
string = "This            is a                      test."

result = re.split(r"( )", string)
# ['This',
# ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ',
# 'is', ' ',
# 'a', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ', '', ' ',
# 'test.']

I can do something like this and achieve the result I want:

string = "This            is a                      test."
result = []

spaces = ''
word = ''
for letter in string:
    if letter == ' ':
        spaces += ' ' 
        if word:
            result.append(word)
            word = ''
    else:
        word += letter
        if spaces:
            result.append(spaces)
            spaces = ''
if spaces:
    result.append(spaces)
if word:
    result.append(word)

print(result)
# ['This', '            ', 'is', ' ', 'a', '                      ', 'test.']

But this doesn't feel like the best way to do it. Is there a more Pythonic way of achieving this?

3 Answers

Try with re.split with the expression of (\s+):

>>> import re
>>> string = "This            is a                      test."
>>> re.split(r'(\s+)', string)
['This', '            ', 'is', ' ', 'a', '                      ', 'test.']
>>> 

Regex101 example.

You can try this:

import re
def main_function(string):
    return re.split(r'(\s+)', string)

print(main_function("This            is a                      test."))

Output:

['This', '            ', 'is', ' ', 'a', '                      ', 'test.']

Example on Regex101.com

You could also avoid doing a string split and instead use re.findall:

string = "This            is a                      test."
matches = re.findall(r'\s+|\S+', string)
print(matches)

This prints:

['This', '            ', 'is', ' ', 'a', '                      ', 'test.']

The regex alternation \s+|\S+ alternatively matches groups of whitespace or non whitespace characters.

Related