2016-08-18 125 views
0

我有一個python字符串,我需要刪除括號。標準方法是使用text = re.sub(r'\([^)]*\)', '', text),因此括號內的內容將被刪除。如何刪除多層圓括號中的文本python

但是,我剛剛發現一個看起來像(Data with in (Boo) And good luck)的字符串。隨着我使用的正則表達式,它仍然有And good luck)部分。我知道我可以掃描整個字符串並嘗試保留一個數字爲()的計數器,並且當數字平衡時,索引()的位置並刪除中間的內容,但是會有更好還是更清晰的方式爲了做到這一點?它不需要是正則表達式,無論它會工作是多麼偉大,謝謝。

有人問了那麼這裏預期的結果是什麼,我期待:

Hi this is a test (a b (c d) e) sentence

更換後我希望它是Hi this is a test sentence,而不是Hi this is a test e) sentence

+1

這是不可能的re模塊做到這一點,但你可以用正則表達式模塊,允許遞歸做到這一點。 https://pypi.python.org/pypi/regex –

+1

在最壞的情況下,如果你建立一個模式來匹配最內層的括號'\([^()] * \),那麼你可以用re模塊來完成它,如果你循環替換,直到沒有任何東西可以替換。但它不是一個非常優雅的方式,因爲你需要多次解析字符串。 –

+0

你對非正則表達式解決方案開放嗎? – Dan

回答

2

通過re模塊(更換最裏面的括號,直到沒有更多的替代辦):

import re 

s = r'Sainte Anne -(Data with in (Boo) And good luck) Charenton' 

nb_rep = 1 

while (nb_rep): 
    (s, nb_rep) = re.subn(r'\([^()]*\)', '', s) 

print(s) 

隨着regex module,允許遞歸:

import regex 

s = r'Sainte Anne -(Data with in (Boo) And good luck) Charenton' 

print(regex.sub(r'\([^()]*+(?:(?R)[^()]*)*+\)', '', s)) 

(?R)指整個模式本身。

+0

第一個答案很美很棒。謝謝。 – JLTChiu

1

首先,我行拆分成做記號不包含括號,以便稍後將其加入新行:

line = "(Data with in (Boo) And good luck)" 
new_line = "".join(re.split(r'(?:[()])',line)) 
print (new_line) 
# 'Data with in Boo And good luck' 
1

沒有正則表達式...

>>> a = 'Hi this is a test (a b (c d) e) sentence' 
>>> o = ['(' == t or t == ')' for t in a] 
>>> o 
[False, False, False, False, False, False, False, False, False, False, 
False, False, False, False, False, False, False, False, True, False, False, 
False, False, False, True, False, False, False, False, True, False, False, 
True, False, False, False, False, False, False, False, False, False] 
>>> start,end=0,0 
>>> for n,i in enumerate(o): 
... if i and not start: 
... start = n 
... if i and start: 
... end = n 
... 
>>> 
>>> start 
18 
>>> end 
32 
>>> a1 = ' '.join(''.join(i for n,i in enumerate(a) if (n<start or n>end)).split()) 
>>> a1 
'Hi this is a test sentence' 
>>> 
1

假設(1)總是有括號匹配;(2)我們只去掉括號,一切都在他們之間(即周圍的空間周圍的括號不變) ,以下應該工作。

它基本上是一個狀態機,它維持嵌套括號的當前深度。如果(1)不是括號,並且(2)當前深度爲0,我們保留字符。

沒有正則表達式。沒有遞歸。沒有任何中間列表的情況下通過輸入字符串單次傳遞。

tests = [ 
    "Hi this is a test (a b (c d) e) sentence", 
    "(Data with in (Boo) And good luck)", 
] 

delta = { 
    '(': 1, 
    ')': -1, 
} 

def remove_paren_groups(input): 
    depth = 0 

    for c in input: 
     d = delta.get(c, 0) 
     depth += d 
     if d != 0 or depth > 0: 
      continue 
     yield c 

for input in tests: 
    print ' IN: %s' % repr(input) 
    print 'OUT: %s' % repr(''.join(remove_paren_groups(input))) 

輸出:

IN: 'Hi this is a test (a b (c d) e) sentence' 
OUT: 'Hi this is a test sentence' 
IN: '(Data with in (Boo) And good luck)' 
OUT: ''