2016-03-09 27 views
4

內屬性我有一個正則表達式,這將{{ expression }}轉換成{% print expression %}時表達{{ function() }}{{ object.function() }}或類似{{ a+b }}算術運算,但不會轉換時,它會得到{{ var }}{{ object.attribute }}正則表達式來排除串並表達

用正則表達式我的問題是轉換字符串表達式{{ "string" }}{{ "function()" }}{{ "{{ var}}" }}{% print "string" %}{% print "function()" %}{% print "{% print var %}" %}

import re 

def replacement(val): 
    content = val.group(1) 
    if re.match('^\s*[\w\.]+\s*$', content): 
     return "{{%s}}" % content 
    else: 
     return "{%% print %s %%}" % content 

string_obj = """{{ var }} {{ object.var }} {{ func()}} {{ object.function() }} {{ a+b }} {{ "string" }} {{ "{{ var }}" }} {{ "function()" }} {{ "a+b" }}""" 

print(re.sub("{{(\s*.*?\s*)}}", replacement, string_obj)) 

輸出:

「{{VAR}} {{對象。%} {%print「string」%} {%print「{{var}}」%%{} print {%printf {%} {%print object.function()%} {%print a + b% } {%print 「function()」%} {%p RINT 「A + B」 %} '

我想要的輸出是:

'{{VAR}} {{object.var}} {%打印FUNC()%} { %print object.function()%} {%print a + b%} {{「string」}} {{「{{var}}」}} {{「function()」 }} {{「a + b」}}」

注:這裏的一個條件是在{{ }}之間可以具有像字符串表達式表達即用雙引號或{{ 'string' }}即用單引號。

+0

據推測,這是因爲你在你的角色組使用'\ w'。你可以用'\「加雙引號,或者不要使用正則表達式,並且測試'」()「'是否在'val.group(1)'中(以及其他任何類似'+ - * /') – Evert

+0

我不能僅僅檢查「()」,因爲我想轉換算術表達式,就像{{a + b}}一樣,如果我檢查「()」,它也會將表達式轉換爲{ {「function()」}}。我只想將{{function()}}或{{a + b}}表達式轉換爲{{「function()」}} {{「a + b」}} –

+0

也許最直接的方法是爲周圍的(雙引號)或周圍的雙花括號添加案例,或者找到一個模板轉換器,它已經完成了你想要做的事情。 – Evert

回答

1

代碼

對於更漂亮的打印,我只是在開始和結束時剝去空白。它也簡化了正則表達式。

import re 

def replacement(val): 
    content = val.group(1).strip() 
    if re.match('^\w[^\.\(\+\*\/\-\|]*\.?\w[^\.\(\+\*\/\-\|]*$', content): 
     return "{{ %s }}" % content 
    else: 
     return "{%% print %s %%}" % content 

def maskString(templateString): 
    stringChars = ['"', "'"] 
    a = 0 
    start = None 
    maskedList = [] 
    while a < len(templateString): 
     l = templateString[a] 
     if l in stringChars and start is None and a-1 >=0 and templateString[a-1] != '\\': 
      start = {'l' : l, 's' : a} 
     elif start is not None and l is start['l'] and a-1 >=0 and templateString[a-1] != '\\': 
      start['e'] = a + 1 
      stringToMask = templateString[start['s']:start['e']] 
      templateString = templateString[:start['s']] + ("_" * len(stringToMask)) + templateString[start['e']:] 
      maskedList.append(stringToMask) 
      start = None 
     a += 1 
    return (templateString, maskedList) 

def unmaskString(templateString, maskedList): 
    for string in maskedList: 
     templateString = templateString.replace("_" * len(string), string,1) 
    return templateString 

def templateMatcher(templateString): 
    p = re.compile('("[^"]*)"') 
    templateString, maskedList = maskString(templateString) 
    templateString = re.sub("{{(\s*.*?\s*)}}", replacement, templateString) 
    return unmaskString(templateString, maskedList) 

string_obj = """{{ var }} {{ object.var }} {{ func()}} {{ object.function() }} {{ a+b }} {{ "string" }} {{ "{{ var }}" }} {{ "function()" }} {{ "a+b" }}""" 
string_obj_2 = """{{ a+b*c-d/100}} {{ 1 * 2 }} {{ 20/10 }} {{ 5-4 }}""" 
string_obj_3 = """{{ "another {{ mask" }} {{ func() }}, {{ a+b }} , {{ "string with \\""|filter }}""" 

print(templateMatcher(string_obj)) 
print(templateMatcher(string_obj_2)) 
print(templateMatcher(string_obj_3)) 

新增了先進的屏蔽爲字符串,這樣"\""'"'將被識別爲字符串,假設變量不可能只由_。字符串的開始和結束字符在變量stringChars中。所以如果你不喜歡'只是從那裏刪除它。

輸出

{{ var }} {{ object.var }} {% print func() %} {% print object.function() %} {% print a+b %} {{ "string" }} {{ "{{ var }}" }} {{ "function()" }} {{ "a+b" }} 
{% print a+b*c-d/100 %} {% print 1 * 2 %} {% print 20/10 %} {% print 5-4 %} 
{{ "another {{ mask" }} {% print func() %}, {% print a+b %} , {% print "string with \""|filter %} 
+0

你的答案是非常正確的,但是在這種模式下,我們可以只查找內容添加符號的算術表達式。我們無法分析suibtraction,乘法模數或劃分僅{{A + B}}將{%打印A + B%}不{{A + B * CD/100}}或{{1 * 2} }或{{20 - 10}}等我們也想將它們轉換成{%打印arithmetic_operation%},除非它們是不是像串{{ 「1·2」}}等 –

+0

@yashlodha'{{A + b * cd/100}}'在我的解決方案中轉換爲'{%打印a + b * cd/100%}'另一個像你提到的那樣。字符串'{{「1 * 2」}}'被轉換爲{{「1 * 2」}}。那麼問題在哪裏? – Kordi

+0

{{1 * 2}} {成打印%1 * 2%}或{{20/10}} {成%的打印十分之二十〇%}或{{5-4}} {成打印%5-4% }。 –