7

我有一个这样的字符串:

这是[括号测试]“和引号测试”

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

['this','is','括号测试','和引号测试']

4

6 回答 6

8

Here's a simplistic solution that works with your test input:

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

This will return any code that matches either

  • a open bracket followed by zero or more non-close-bracket characters followed by a close bracket,
  • a double-quote followed by zero or more non-quote characters followed by a quote,
  • any group of non-whitespace characters

This works with your example, but might fail for many real-world strings you may encounter. For example, you didn't say what you expect with unbalanced brackets or quotes,or how you want single quotes or escape characters to work. For simple cases, though, the above might be good enough.

于 2008-10-24T17:57:26.260 回答
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 ']

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

于 2008-10-24T22:07:04.277 回答
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 = '"'
于 2008-10-24T18:04:26.403 回答
0

好吧,我已经多次遇到这个问题,这导致我编写了自己的系统来解析任何类型的语法。

结果可以在这里找到;请注意,这可能是多余的,它会为您提供一些东西,让您可以根据需要解析带有括号和括号、单引号和双引号的语句。例如,您可以解析这样的内容(用 Common Lisp 编写的示例):

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

您可以使用嵌套、方括号(方)和圆括号(圆)、单引号和双引号字符串,而且它的可扩展性非常好。

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

于 2008-10-26T19:17:49.740 回答
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
于 2008-10-24T19:28:32.707 回答
-2

仅适用于报价。

rrr = []
qqq = s.split('\"')
[ rrr.extend( qqq[x].split(), [ qqq[x] ] )[ x%2]) for x in range( len( qqq ) )]
print rrr
于 2008-10-24T18:56:54.300 回答