2011-11-06 200 views
2

我有點卡在正則表達式中。我在格式Python正則表達式 - 替換大括號之間的所有字符

{% 'ello %} wor'ld {% te'st %} 

一個字符串,我想逃避僅限未{% ... %}標籤之間的撇號,所以預期輸出是

{% 'ello %} wor"ld {% te'st %} 

我知道我可以只更換所有的人使用字符串replace函數,但我不知道如何使用正則表達式來匹配那些外部大括號

+0

可你{ % 瘦gies%}巢? – tchrist

回答

5

這可能可以用正則表達式來完成,但它會是一個複雜的。它更容易讀寫,如果你只是做它直接:

def escape(s): 
    isIn = False 
    ret = [] 
    for i in range(len(s)): 
     if not isIn and s[i]=="'": ret += ["""] 
     else: ret += s[i:i+1] 

     if isIn and s[i:i+2]=="%}": isIn = False 
     if not isIn and s[i:i+2]=="{%": isIn = True 

    return "".join(ret) 
+0

+1:正則表達式在這裏是錯誤的工具。你需要修復你的功能。 *標籤中的*不*應該被轉義,所以''如果isIn和s [i] ==''「...''應該是''如果不是''''''。 – Blair

+0

好點,謝謝 –

+2

誰downvoted,請你解釋爲什麼。 –

3

只是爲了好玩,這是用正則表達式來做到這一點:

>>> instr = "{% 'ello %} wor&quote;ld {% te'st %}" 
>>> re.sub(r'\'(?=(.(?!%}))*({%|$))', r'&quote;', instr) 
"{% 'ello %} wor&quote;ld {% te'st %}" 

它採用了積極的展望既找不到{%或字符串的結尾,以及積極向前的負向預測,以確保它不包含任何%}。

2

如果你想使用正則表達式,你可以像這樣做雖然:

>>> s = """'{% 'ello %} wor'ld {% te'st %}'""" 
>>> segments = re.split('(\{%.*?%\})', s) 
>>> for i in range(0, len(segments), 2): 
    segments[i] = segments[i].replace('\'', '"') 

>>> ''.join(segments) 
""{% 'ello %} wor"ld {% te'st %}"" 

與伊赫桑的前瞻的解決方案相比,該有,你可以運行在任何類型的更換或分析的好處段不需要重新運行另一個正則表達式。所以如果你決定替換另一個角色,你可以很容易地在循環中做到這一點。

0

bcloughlan,復活這個問題,因爲它有一個沒有提到的簡單解決方案。 (發現你的問題而做一些研究的一般問題有關how to exclude patterns in regex

這裏有一個簡單的正則表達式:

{%.*?%}|(\') 

交替的左側完整{% ... %}標籤相匹配。我們將忽略這些匹配。右側與第1組相匹配並捕獲撇號,並且我們知道它們是正確的撇號,因爲它們與左側的表達不匹配。

這個程序演示瞭如何使用正則表達式(見online demo結果):

import re 
subject = "{% 'ello %} wor'ld {% te'st %}" 
regex = re.compile(r'{%.*?%}|(\')') 
def myreplacement(m): 
    if m.group(1): 
     return """ 
    else: 
     return m.group(0) 
replaced = regex.sub(myreplacement, subject) 
print(replaced) 

參考

  1. How to match pattern except in situations s1, s2, s3
  2. How to match a pattern unless...
相關問題