在Python中分割字符串
我有一个这样的字符串:
this is [bracket test] "and quotes test "
我想用Python写个程序,把这个字符串按空格分开,但要忽略方括号和引号里面的空格。最终我想要的结果是:
['this','is','bracket test','and quotes test ']
6 个回答
1
这里有一个简单的解析器(已经用你的示例输入测试过),它介绍了状态设计模式。
在现实中,你可能想用像 PLY 这样的工具来构建一个真正的解析器。
class SimpleParser(object):
def __init__(self):
self.mode = None
self.result = None
def parse(self, text):
self.initial_mode()
self.result = []
for word in text.split(' '):
self.mode.handle_word(word)
return self.result
def initial_mode(self):
self.mode = InitialMode(self)
def bracket_mode(self):
self.mode = BracketMode(self)
def quote_mode(self):
self.mode = QuoteMode(self)
class InitialMode(object):
def __init__(self, parser):
self.parser = parser
def handle_word(self, word):
if word.startswith('['):
self.parser.bracket_mode()
self.parser.mode.handle_word(word[1:])
elif word.startswith('"'):
self.parser.quote_mode()
self.parser.mode.handle_word(word[1:])
else:
self.parser.result.append(word)
class BlockMode(object):
end_marker = None
def __init__(self, parser):
self.parser = parser
self.result = []
def handle_word(self, word):
if word.endswith(self.end_marker):
self.result.append(word[:-1])
self.parser.result.append(' '.join(self.result))
self.parser.initial_mode()
else:
self.result.append(word)
class BracketMode(BlockMode):
end_marker = ']'
class QuoteMode(BlockMode):
end_marker = '"'
5
为了补充Bryan的帖子,并准确匹配他的回答:
>>> import re
>>> txt = 'this is [bracket test] "and quotes test "'
>>> [x[1:-1] if x[0] in '["' else x for x in re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+', txt)]
['this', 'is', 'bracket test', 'and quotes test ']
不要误解这里使用的语法:这不是在一行中写了多个语句,而是一个单一的功能语句(这样更不容易出错)。
8
这里有一个简单的解决方案,可以处理你的测试输入:
import re
re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+',s)
这个代码会返回任何符合以下条件的内容:
- 一个开括号后面跟着零个或多个不是闭括号的字符,然后是一个闭括号,
- 一个双引号后面跟着零个或多个不是引号的字符,然后是一个引号,
- 任何一组不是空格的字符
这个方法在你的例子中有效,但在很多实际情况中可能会出问题。例如,你没有说明当括号或引号不匹配时你希望怎么处理,也没有说单引号或转义字符应该怎么工作。不过,对于简单的情况来说,上面的方案可能已经足够了。