Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python split string with space unless a \ is in front

Sorry if this post is a bit confusing to read this is my first post on this site and this is a hard question to ask, I have tried my best. I have also tried googling and i can not find anything.

I am trying to make my own command line like application in python and i would like to know how to split a string if a "\" is not in front of a space and to delete the backslash.

This is what i mean.

>>> c = "play song I\ Want\ To\ Break\ Free"
>>> print c.split(" ")
['play', 'song', 'I\\', 'Want\\', 'To\\', 'Break\\', 'Free']

When I split c with a space it keeps the backslash however it removes the space. This is how I want it to be like:

>>> c = "play song I\ Want\ To\ Break\ Free"
>>> print c.split(" ")
['play', 'song', 'I ', 'Want ', 'To ', 'Break ', 'Free']

If someone can help me that would be great!

Also if it needs Regular expressions could you please explain it more because I have never used them before.

Edit: Now this has been solved i forgot to ask is there a way on how to detect if the backslash has been escaped or not too?

like image 751
iProgram Avatar asked Apr 18 '14 17:04

iProgram


People also ask

How do you split a string with spaces in Python?

The split() method splits a string into a list. You can specify the separator, default separator is any whitespace. Note: When maxsplit is specified, the list will contain the specified number of elements plus one.

How do you split a space and a new line in Python?

Use split() method to split by delimiter. If the argument is omitted, it will be split by whitespace, such as spaces, newlines \n , and tabs \t . Consecutive whitespace is processed together. A list of the words is returned.

How do you split first space in Python?

Use the str. split() method with maxsplit set to 1 to split a string only on the first space, e.g. my_str. split(' ', 1) . The split() method only performs a single split when the maxsplit argument is set to 1 .


2 Answers

It looks like you're writing a commandline parser. If that's the case, may I recommend shlex.split? It properly splits a command string according to shell lexing rules, and handles escapes properly. Example:

>>> import shlex
>>> shlex.split('play song I\ Want\ To\ Break\ Free')
['play', 'song', 'I Want To Break Free']
like image 122
nneonneo Avatar answered Nov 09 '22 01:11

nneonneo


Just split on the space, then replace any string ending with a backslash with with one ending in a space instead:

[s[:-1] + ' ' if s.endswith('\\') else s for s in c.split(' ')]

This is a list comprehension; c is split on spaces, and each resulting string is examined for a trailing \ backslash at the end; if so, the last character is removed and a space is added.

One slight disadvantage: if the original string ends with a backslash (no space), that last backslash is also replaced by a space.

Demo:

>>> c = r"play song I\ Want\ To\ Break\ Free"
>>> [s[:-1] + ' ' if s.endswith('\\') else s for s in c.split(' ')]
['play', 'song', 'I ', 'Want ', 'To ', 'Break ', 'Free']

To handle escaped backslashes, you'd count the number of backslashes. An even number means the backslash is escaped:

[s[:-1] + ' ' if s.endswith('\\') and (len(s) - len(s.rstrip('\\'))) % 2 == 1 else s
 for s in c.split(' ')]

Demo:

>>> c = r"play song I\ Want\ To\ Break\\ Free"
>>> [s[:-1] + ' ' if s.endswith('\\') and (len(s) - len(s.rstrip('\\'))) % 2 == 1 else s
...  for s in c.split(' ')]
['play', 'song', 'I ', 'Want ', 'To ', 'Break\\\\', 'Free']
like image 23
Martijn Pieters Avatar answered Nov 09 '22 00:11

Martijn Pieters