在Python中分割字符串

7 投票
6 回答
5237 浏览
提问于 2025-04-11 09:30

我有一个这样的字符串:

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)

这个代码会返回任何符合以下条件的内容:

  • 一个开括号后面跟着零个或多个不是闭括号的字符,然后是一个闭括号,
  • 一个双引号后面跟着零个或多个不是引号的字符,然后是一个引号,
  • 任何一组不是空格的字符

这个方法在你的例子中有效,但在很多实际情况中可能会出问题。例如,你没有说明当括号或引号不匹配时你希望怎么处理,也没有说单引号或转义字符应该怎么工作。不过,对于简单的情况来说,上面的方案可能已经足够了。

撰写回答