2016-05-30 10 views
4

私はこのような文字列があります。hereが説明したように、私は簡単に文字列の外側の括弧間のすべてのテキストを削除するにはどうすればよいですか?

# returns 'stuff' 
res1 = re.sub(r'\([^)]*\)', '', s1) 

を使用中に括弧やテキストを削除することができ

s1 = 'stuff(remove_me)' 

を。

しかし、私は時々、このようなネストされた表現に遭遇:

s2 = 'stuff(remove(me))' 

私は上からコマンドを実行すると、私は、私も試してみました

'stuff)' 

で終わる:

re.sub('\(.*?\)', '', s2) 

を私には同じ出力が得られます。

外側のかっこ内のすべて(括弧自体を含む)を削除するにはどうすればいいですか?'stuff'(これは任意の複雑な式にも有効です)にもなりますか? 、あなたは括弧が最初にバランスがとれていることが確実な場合

>>> re.sub(r'\(.*\)', '', 'stuff(remove(me))') 
'stuff' 
+0

チェックを参照してください。 //stackoverflow.com/a/14598135/3832970)。 –

+0

@WiktorStribiżew:ありがとう!しかし、それは入れ子になっていない表現についてです。そして、多くのif-else節とfor-loopを必要としないものが存在することは確かです。 – Cleb

+1

あなたが必要とする正規表現はこの[answer](http://stackoverflow.com/a/12280660/3832970)に含まれていますが、PyPi regexモジュールが必要です。 –

答えて

2

re試合はあなただけで正規表現実行させ言及簡単なテストケースのために、熱望しています

re.sub(r'\(.*\)', '', s2) 
+0

ああ、それは簡単だった...ありがとう! – Cleb

+3

@これは中括弧が一致するかどうかをチェックしないことを警告します。例えば。 'foo(bar)baz(spam)e)ggs'では' fooggs'だけ残します。 –

+0

@ivan_pozdeev:警告ありがとう、知っておいてよかった!私の例では一致するはずですが、とにかく小切手を追加します。 – Cleb

1

:彼らはできるだけ多くのテキストを一致させようとして

+0

ありがとう、@アレクサミミの答えと同じですが、まだupvoteに値する。とても単純です... – Cleb

0

https://regex101.com/r/kQ2jS3/1

'(\(.*\))' 
:ちょうど 貪欲バージョンを使用

これは、かっこの間にあるfurthestカッコとすべてをキャプチャします。

あなたの古い正規表現は、最初のカッコとその間のすべてを括弧の末尾にキャプチャします(next)。あなたがネストの任意のレベルを一致させるためrecursive regexを必要があると思いますが、あなたが知っている場合にのみ、ネストの1つのレベルの最大があることができ

+0

他の2つの答えと同じですが、とにかく感謝しています... :) – Cleb

2

前に述べたように、このパターンで試してみる:

\((?:[^)(]|\([^)(]*\))*\) 
  • [^)(]は、括弧ではない文字と一致します(negated class)。
  • |\([^)(]*\)またはそれは内部)(の任意の量で、別()ペアと一致。
  • (?: ...)*すべてこの()

Here is a demo at regex101

内部倍の任意の量交代がアンバランスな場合はより速く失敗する+数量詞なし[^)(]を使用する前に。
発生する可能性のあるネスティングのレベルを追加する必要があります。例えば、最大2つのレベルのために:

\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\) 

Another demo at regex101

+0

詳細な説明(upvoted)に感謝します。 – Cleb

5

\(.*\)は左から最初(と一致し、(DOTALL修飾子が有効でない場合には改行以外の)その後、任意の0+文字に一致します最後に)になり、正しくネストされたかっこは考慮されません。

あなたは、単純な\([^()]*\)(をマッチングし、0+その後、())以外の文字)しばらくブロック内で使用して使用することができ、Pythonのに正規表現で正しくネストされた括弧を削除するには re.subn:Bascially

def remove_text_between_parens(text): 
    n = 1 # run at least once 
    while n: 
     text, n = re.subn(r'\([^()]*\)', '', text) # remove non-nested/flat balanced parts 
    return text 

:一致が見つからなくなるまで内側に無()(...)を削除します。使用法:

print(remove_text_between_parens('stuff (inside (nested) brackets) (and (some(are)) here) here')) 
# => stuff here 

非正規表現の方法も可能である:

def removeNestedParentheses(s): 
    ret = '' 
    skip = 0 
    for i in s: 
     if i == '(': 
      skip += 1 
     elif i == ')'and skip > 0: 
      skip -= 1 
     elif skip == 0: 
      ret += i 
    return ret 

x = removeNestedParentheses('stuff (inside (nested) brackets) (and (some(are)) here) here') 
print(x)    
# => 'stuff here' 

は(HTTP [\ [\] Pythonで*間のテキスト()とを削除*] another Python demo

+0

非常に有益な例、感謝(upvoted)! – Cleb

関連する問題