Python字符串分割,除非有 \ 在前面。

8
很抱歉,如果这篇文章不太容易阅读,这是我在该网站上发布的第一篇文章,这是一个很难问的问题,我已经尽力了。我也试过谷歌搜索,但什么都找不到。
我正在尝试在Python中制作自己的命令行应用程序,并想知道如何在一个反斜杠(\)不在空格前面时分割字符串并删除反斜杠。
这就是我的意思。
>>> c = "play song I\ Want\ To\ Break\ Free"
>>> print c.split(" ")
['play', 'song', 'I\\', 'Want\\', 'To\\', 'Break\\', 'Free']

当我使用空格分割 c 时,它会保留反斜杠,但会移除空格。这是我想要的效果:
>>> c = "play song I\ Want\ To\ Break\ Free"
>>> print c.split(" ")
['play', 'song', 'I ', 'Want ', 'To ', 'Break ', 'Free']

如果有人能帮助我那就太好了!如果需要使用正则表达式,能否请您更详细地解释一下,因为我以前从未使用过它们。编辑:现在这个问题已经解决了,我忘了问是否有一种方法可以检测反斜杠是否被转义了。

我一开始误解了;您确实想要按空格拆分,但是当空格前面有反斜杠时,您希望保留空格作为拆分字符串的一部分。检查 - Martijn Pieters
2个回答

13

看起来你正在编写一个命令行解析器。如果是这样,我可以推荐 shlex.split 吗?它可以根据Shell词法规则正确地分割命令字符串,并且可以正确地处理转义字符。例如:

>>> import shlex
>>> shlex.split('play song I\ Want\ To\ Break\ Free')
['play', 'song', 'I Want To Break Free']

太棒了!正是我想要的!它甚至知道如果在引号内就不要分割!谢谢。 :) 这很有用,因为它将成为 raw_input() 的输入,所以如果有引号就不要分割!谢谢。 - iProgram
@aPyDeveloper:我还以为你想要生成演示的输出呢! :-) - Martijn Pieters
它已经得到了我想要的输出。 - iProgram

2

只需在空格上拆分,然后将任何以反斜杠结尾的字符串替换为以空格结尾的字符串即可:

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

这是一个列表推导式; 将c按空格分割,然后检查每个结果字符串是否以\反斜杠结尾; 如果是,则删除最后一个字符并添加一个空格。
一个小缺点:如果原始字符串以反斜杠(没有空格)结尾,则最后一个反斜杠也会被替换为一个空格。
演示:
>>> 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']

要处理转义反斜杠,您需要计算反斜杠的数量。如果是偶数,则表示反斜杠已被转义:

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

演示:

>>> 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']

如果字符串以反斜杠结尾,这会发生什么? - Rose Kunkel
@WilliamKunkel:最后一个反斜杠也被替换了。嗯。 - Martijn Pieters
我刚刚更新了我的任务,如果你也想帮我完成它的话,就来吧!;) - iProgram
@aPyDeveloper:你需要计算字符串末尾反斜杠的数量;如果数量是偶数,则反斜杠已被转义。len(s) - len(s.rstrip('\\')) 可以告诉你字符串末尾有多少个反斜杠。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接