2015-10-20 118 views
-4

我試圖用{{]]替換[[並將}}替換爲文件。
但是,如果連續有2個以上的方括號,我只想在最內層的2個括號中工作。
所以,如果我有這樣的:[[[[它應該[[{{取代,]]]]應該}}]]Python替換字符串中最內層的2個括號字符

+2

好的!你曾經嘗試過什麼,它有什麼問題?我會推薦一個負面的lookarounds正則表達式。 – jonrsharpe

+0

我之前沒有使用過正則表達式,到目前爲止腳本只是使用String.replace(「[[」,「{{」)。但是,這對於超過2個連續字符無法正常工作 – user3473280

+4

是的,這不起作用。開始查看正則表達式(https://docs.python.org/2/library/re.html)並查看例如https://regex101.com/r/wU2yF9/2。但是,SO既不是代碼編寫,也不是教程服務。 – jonrsharpe

回答

-1

使用正則表達式,你可以使用向前看符號和lookbehinds替換爲:

>>> import re 
>>> s = "[[{{ }}]] [[ ]]" 
>>> s = "[[[[ ]]]] [[ ]]" 
>>> a = re.sub("(?<=\[{2})\[\[","{{",s) 
>>> a 
'[[{{ ]]]] [[ ]]' 
>>> a = re.sub("(?=\]{4})\]\]","}}",s) 
>>> a 
'[[[[ }}]] [[ ]]' 
+0

使用積極的變換使得它非常不靈活 - 爲什麼不是*消極*變換? – jonrsharpe

-2

有可能比一個更好的正則表達式我的,但這是一個快速解決方案。

import re 
p = re.compile(ur'(.*)\[{3}(.*?)\]{3}(.*)') 
test_str = u"[[[[ text ]]]]" 
matches = re.match(p, test_str) 
if matches: 
    print matches.group(1) + '[{{' + matches.group(2) + '}}]' + matches.group(3) 
    # [[{{ text }}]] 
+0

剛纔我問了OP。他希望所有的括號都替換掉,因爲我理解他對我評論的回答。 – saulspatz

+0

我明白了。更新了答案。 –

+0

現在這對''[[text]]「'('」{{text}}「')不起作用,它對於'[[first]] [[second]]不起作用」 ''{{first}} {{second}}「')或''[[one [[two]] three]]''('」{{one {{two}} three}}'') –

0

可以使用負前瞻(找到最裏面的左括號)和負向後看(找到最裏面的右括號):

>>> import re 
>>> original = "[This] [[is]] [[[a]]] [[[[test]]]]" 
>>> left_replaced = re.sub("\[\[(?!\[)", "{{", original) 
>>> left_replaced 
'[This] {{is]] [{{a]]] [[{{test]]]]' 
>>> result = re.sub("(?<!\])\]\]", "}}", left_replaced) 
>>> result 
'[This] {{is}} [{{a}}] [[{{test}}]]' 

注意,這將取代四方形雖然正則表達式是最好的方式

>>> original = "[This] [[is]] [[[a]]] [[ [[test]] ]]" 
>>> left_replaced = re.sub("\[\[(?!\[)","{{",original) 
>>> left_replaced 
'[This] {{is]] [{{a]]] {{ {{test]] ]]' 
>>> result = re.sub("(?<!\])\]\]", "}}", left_replaced) 
>>> result 
'[This] {{is}} [{{a}}] {{ {{test}} }}' 
+1

如果需要,您可以避免使用'\ s *'分隔空間的情況。 – jonrsharpe

+0

是的,'\ s *'會進入每種情況的負面預測/背後:'\ [\ [(?!\ s * \ [)'和'(?<!\] \ s * )\] \]' –

+0

我沒有看到爲了替換必須有兩個以上的連續的要求,所以我更新了我的答案來處理這個問題。 –

0

:在一排支架,如果兩對之間用空格或任何其他字符(這是從你的問題不清楚,你想怎麼處理這種情況)分離

string = '[[abc[[cde]]ghi]]]]' 
leftBrackets = [i for i in range(len(string)-1) if string[i:i+2] == '[[' and 
    (i == len(string)-2 or string[i+2] != '[')] 
rightBrackets = [i for i in range(len(string)-1) if string[i:i+2] == ']]' and 
    (i == len(string)-2 or string[i+2] != ']')] 
for index in leftBrackets: 
    string = string[:index] + '{{' + string[index+2:] 
for index in rightBrackets: 
    string = string[:index] + '}}' + string[index+2:] 
print(string) 

這將打印

{{abc{{cde}}ghi]]}} 

:這樣做,如果效率是一個重要的考慮因素,如果你只有中等長度的幾千串,你可以用代碼更加易讀做到這一點正則表達式是非常棒的,如果你擅長使用它們,但我不是。我已經經歷了「掌握正則表達式」,但我沒有太多機會使用它們,所以我已經忘記了除了最基本的東西之外的所有東西。雖然我可以查看先進的東西,但我無法記住它,所以在一個星期左右之後,我的代碼變得難以理解。因此,我甚至不會考慮使用正則表達式來處理這樣的事情,除非像上面這樣直截了當的代碼變得太慢了。

當然,其他人會不同意我的觀點,並留下粗魯的評論,但您可能要考慮我對此事的看法。

順便說一句,在實踐中,我會將leftBrackets和rightBrackets的定義放在try except塊中,並取消範圍末尾的檢查。

+0

我認爲花時間更好地理解正則表達式會比上面的代碼好很多。該代碼效率會低得多,而且更加冗長。 ''re.sub(「([<!!])\] \]」,「}}」,re.sub(「\ [\ [(?!\ [)」,「{{」,s))'你需要用正則表達式來完成這一切。那裏唯一的「先進的東西」是事實,你必須小心逃避括號和負面看,其實並不複雜。我並不是想抨擊你的答案,我只是不認爲這是最好的建議。 –

+0

此外,期望的結果是'{{abc {{cde}} ghi}}]]',而不是'{{abc {{cde}} ghi]]}}' –

+0

@Jake Griffith我明白你在說什麼,但我不同意。正則表達式很好,如果你做了很多文本處理,但如果你不這樣做,它們不是很有價值。我發現,無論何時我決定使用正則表達式(曾經是一個藍色的月亮),我都不得不花費大量的時間重新學習它們。我猜這是在我寫這篇文章時誤解了規範,但我不會在修復它時遇到任何麻煩,因爲我可以閱讀它在做什麼。是。它冗長,不雅,低效,但如果我只需要將文件轉換爲另一種格式,誰在乎呢? – saulspatz