7

私はこのような文字列を持っています:

これは[ブラケットテスト]"と引用符テスト"です

中括弧と引用符内のスペースを無視して、Pythonで何かをスペースで分割するように作成しようとしています。私が探している結果は次のとおりです。

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

4

6 に答える 6

8

テスト入力で機能する単純なソリューションを次に示します。

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

これにより、いずれかに一致するコードが返されます

  • 左大括弧の後に 0 個以上の非右大括弧文字が続き、その後に右大括弧が続きます。
  • 二重引用符の後に 0 個以上の引用符以外の文字が続き、その後に引用符が続きます。
  • 非空白文字の任意のグループ

これはあなたの例では機能しますが、実際に遭遇する可能性のある多くの文字列では失敗する可能性があります。たとえば、アンバランスな括弧や引用符で何を期待するか、単一引用符やエスケープ文字をどのように機能させたいかを言いませんでした。ただし、単純なケースでは、上記で十分な場合があります。

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

使用されている構文全体を誤解しないでください。これは、1 行に複数のステートメントがあるのではなく、1 つの関数ステートメントです (よりバグ防止)。

于 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

より手続き的なアプローチは次のとおりです。

#!/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 に答える
0

さて、私はこの問題に何度も遭遇したため、あらゆる種類の構文を解析するための独自のシステムを作成することになりました。

この結果はここにあります。これはやり過ぎかもしれないことに注意してください。これにより、ブラケットと括弧の両方、一重引用符と二重引用符を必要に応じてネストしてステートメントを解析できるようになります。たとえば、次のようなものを解析できます (Common Lisp で書かれた例):

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

ネスト、括弧 (四角) と括弧 (丸)、一重引用符と二重引用符で囲まれた文字列を使用でき、非常に拡張性があります。

このアイデアは基本的に、文字ごとに抽象的な構文ツリーを構築する有限状態マシンの構成可能な実装です。ソース コード (上記のリンクを参照) を参照して、その方法を理解することをお勧めします。正規表現を介して可能ですが、RE を使用してシステムを作成し、後でそれを拡張する (または理解する) ことを試みてください。

于 2008-10-26T19:17:49.740 に答える
-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 に答える