在python中拆分字符串

时间:2008-10-24 17:33:42

标签: python string split parsing tokenize

我有一个像这样的字符串:

这是[括号测试]“并引用测试”

我正在尝试用Python编写一些东西,用空格分割它,同时忽略方括号和引号中的空格。我正在寻找的结果是:

['this','is','bracket test','and quotes test']

6 个答案:

答案 0 :(得分:8)

这是一个与您的测试输入一起使用的简单解决方案:

import re
re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+',s)

这将返回与

匹配的任何代码
  • 一个开括号,后跟零个或多个非近括号字符后跟一个右括号
  • 双引号后跟零个或多个非引号字符后跟引号,
  • 任何非空白字符组

这适用于您的示例,但对于您可能遇到的许多真实字符串可能会失败。例如,您没有说出您对不平衡括号或引号的期望,或者您希望单引号或转义字符如何工作。但是,对于简单的情况,上述情况可能还不错。

答案 1 :(得分:5)

完成布莱恩的帖子并完全匹配答案:

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

不要误解所使用的整个语法:这不是单行上的几个语句,而是单个功能语句(更多的错误)。

答案 2 :(得分:1)

这是一个简单的解析器(针对您的示例输入进行测试),它引入了State设计模式。

在现实世界中,您可能希望使用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 = '"'

答案 3 :(得分:0)

这是一种更具程序性的方法:

#!/usr/bin/env python

a = 'this is [bracket test] "and quotes test "'

words = a.split()
wordlist = []

while True:
    try:
        word = words.pop(0)
    except IndexError:
        break
    if word[0] in '"[':
        buildlist = [word[1:]]
        while True:
            try:
                word = words.pop(0)
            except IndexError:
                break
            if word[-1] in '"]':
                buildlist.append(word[:-1])
                break
            buildlist.append(word)
        wordlist.append(' '.join(buildlist))
    else:
        wordlist.append(word)

print wordlist

答案 4 :(得分:0)

好吧,我已经遇到过很多次这个问题了,这让我编写了自己的系统来解析任何一种语法。

可以找到here的结果;请注意,这可能是过度的,并且它将为您提供一些东西,允许您使用括号和括号,单引号和双引号来解析语句,如您所希望的那样嵌套。例如,你可以解析这样的东西(用Common Lisp编写的例子):

(defun hello_world (&optional (text "Hello, World!"))
    (format t text))

您可以使用嵌套,方括号(方括号)和括号(圆形),单引号和双引号字符串,并且它非常易于扩展。

这个想法基本上是有限状态机的可配置实现,它逐个字符地构建抽象语法树。我建议你查看源代码(参见上面的链接),这样你就可以了解如何做到这一点。它可以通过正则表达式,但尝试使用RE编写系统,然后尝试扩展它(甚至理解它)。

答案 5 :(得分:-2)

仅适用于报价。

rrr = []
qqq = s.split('\"')
[ rrr.extend( qqq[x].split(), [ qqq[x] ] )[ x%2]) for x in range( len( qqq ) )]
print rrr