我有一个看起来像这样的字符串:
1. "foo bar"
2. "foo bar foo:bar"
3. "foo bar "
4. "foo bar "
5. "foo bar foo:bar:baz"
我想拆分这个字符串,以便得到以下结果:
1. ['foo', 'bar']
2. ['foo', 'bar', 'foo', ':', 'bar']
3. / 4. ['foo', 'bar', '']
5. ['foo', 'bar', 'foo', ':', 'bar', ':', 'baz']
换句话说,遵循以下规则:
在每次出现空格时分割字符串。
一个。如果字符串末尾有一个或多个空格,则在拆分列表中添加一个空字符串
B.字符串中最后一个非空格字符之前的任何空格都应该被消耗掉,而不是添加到拆分列表中。
在每次出现冒号时拆分字符串,并且不要消耗冒号。
XY 问题是这样的,以防万一:
我想模仿 Bash 选项卡完成行为。当您在 Bash 解释器中键入命令时,它会将命令拆分为数组 COMP_WORDS
,并且它将遵循上述规则 - 基于空格和冒号拆分单词,将冒号放入其自己的数组元素中,和空格被忽略,除非它们位于字符串的末尾。我想在 Python 中重新创建这种行为,给定一个字符串,该字符串看起来像用户会键入的命令。
我已经看到 this question 关于使用 re.split
拆分字符串并保留分隔符。和 this question 关于使用多个分隔符进行拆分。但我的用例更复杂,似乎没有一个问题涵盖它。我尝试了以下至少在空格和冒号上拆分:
print(re.split('(:)|(?: )', splitstr))
但即使这样也行不通。当 splitstr
为 "foo bar foo:bar" 时返回:
['foo', None, 'bar', None, 'foo', ':', 'bar']
知道如何在 Python 中做到这一点吗?
编辑:我的要求不清楚 - 我希望“foo bar”(末尾有任意数量的空格)返回列表 ["foo", "bar", ""]
(只有一个空列表末尾的字符串。)
答案 0 :(得分:1)
您可以在此处使用 re.findall
方法:
[^:\s]+|:|(?<=\S)(?=\s+$)
参见regex demo。 详情:
[^:\s]+
- 除了空格和 :
|
- 或:
- 一个冒号|
- 或(?<=\S)(?=\s+$)
- 位于非空格和字符串末尾的一个或多个空格之间的任何空字符串。参见Python demo。
import re
l = ['foo bar', 'foo bar foo:bar', 'foo bar ', 'foo bar ']
rx = re.compile(r'[^:\s]+|:|(?<=\S)(?=\s+$)')
for s in l:
if s.rstrip() != s:
s = s.rstrip() + " "
print(f"'{s}'", '=>', rx.findall(s))
输出:
'foo bar' => ['foo', 'bar']
'foo bar foo:bar' => ['foo', 'bar', 'foo', ':', 'bar']
'foo bar ' => ['foo', 'bar', '']
'foo bar ' => ['foo', 'bar', '']