6

私は少し前に質問をしました ( Python が不明な文字列をスペースと括弧で分割する) は、考え方を変えなければならないまでうまくいきました。私はまだ正規表現を理解していないので、これについて助けが必要です。

ユーザーがこれを入力した場合:

new test (test1 test2 test3) test "test5 test6"

次のような変数への出力のようにしたいと思います。

["new", "test", "test1 test2 test3", "test", "test5 test6"]

つまり、スペースで区切られた 1 つの単語の場合は次の単語から分割し、括弧内にある場合は括弧内の単語のグループ全体を分割して削除します。引用符についても同様です。

私は現在、上記の基準を満たしていないこのコードを使用しています(上記のリンクの回答から):

>>>import re
>>>strs = "Hello (Test1 test2) (Hello1 hello2) other_stuff"
>>>[", ".join(x.split()) for x in re.split(r'[()]',strs) if x.strip()]
>>>['Hello', 'Test1, test2', 'Hello1, hello2', 'other_stuff']

これはうまく機能しますが、次の場合は問題があります。

strs = "Hello Test (Test1 test2) (Hello1 hello2) other_stuff"

Hello と Test を 2 つではなく 1 つの分割として結合します。

また、括弧と引用符の分割を同時に使用することもできません。

4

5 に答える 5

3

これは、正規表現ができることを後押ししています。pyparsing代わりに使用することを検討してください。再帰的な降下を行います。このタスクでは、以下を使用できます。

from pyparsing import *
import string, re

RawWord = Word(re.sub('[()" ]', '', string.printable))
Token = Forward()
Token << ( RawWord | 
           Group('"' + OneOrMore(RawWord) + '"') |
           Group('(' + OneOrMore(Token) + ')') )
Phrase = ZeroOrMore(Token)

Phrase.parseString(s, parseAll=True)

これは、奇妙な空白に対して堅牢であり、ネストされた括弧を処理します。また、大きな正規表現よりも少し読みやすいため、微調整が容易です。

問題を解決してからずいぶん経っていることは承知していますが、これはこのような問題に関して Google で最もランク付けされているページの 1 つであり、pyparsing はあまり知られていないライブラリです。

于 2017-04-07T18:16:56.313 に答える
1

これはあなたが期待することをしています

import re, itertools
strs = raw_input("enter a string list ")

res1 = [ y for y in list(itertools.chain(*[re.split(r'\"(.*)\"', x) 
        for x in re.split(r'\((.*)\)', strs)])) 
        if y <> '']

set1 = re.search(r'\"(.*)\"', strs).groups()
set2 = re.search(r'\((.*)\)', strs).groups()

print [k for k in res1 if k in list(set1) or k in list(set2) ] 
   + list(itertools.chain(*[k.split() for k in res1 if k 
   not in set1 and k not in set2 ]))
于 2013-06-28T07:30:11.787 に答える
1

あなたの問題は明確に定義されていません。

あなたのルール説明は

つまり、スペースで区切られた 1 つの単語の場合は次の単語から分割し、括弧内にある場合は括弧内の単語のグループ全体を分割して削除します。カンマについても同様です。

コンマとは、逆コンマ == 引用符を意味すると思います。

じゃあこれで

strs = "Hello (Test1 test2) (Hello1 hello2) other_stuff"

あなたはそれを取得する必要があります

["Hello (Test1 test2) (Hello1 hello2) other_stuff"]

すべてが逆コンマで囲まれているためです。おそらく、最大の逆コンマを気にせずに作業したいでしょう。

ボットは醜いですが、私はこれを提案します

import re, itertools
strs = raw_input("enter a string list ")

print [ y for y in list(itertools.chain(*[re.split(r'\"(.*)\"', x) 
        for x in re.split(r'\((.*)\)', strs)])) 
        if y <> '']

取得

>>> 
enter a string list here there (x y ) thereagain "there there"
['here there ', 'x y ', ' thereagain ', 'there there']
于 2013-06-27T21:31:58.307 に答える