Python 正则表达式以排除表达式中的字符串和属性
我有一个正则表达式,当表达式是Python 正则表达式以排除表达式中的字符串和属性,python,regex,string,algorithm,Python,Regex,String,Algorithm,我有一个正则表达式,当表达式是{function()}或{object.function()}或{object.function()}或类似{a+b}的算术运算时,它将转换为{print expression%},但当它得到{var}或{object attribute attribute 我使用的正则表达式的问题是,它将字符串表达式{{“string”}或{{“function()”}或{{{{{var}}}}转换为{%print“string”%}或{%print”function()“%}
{function()}
或{object.function()}
或{object.function()}
或类似{a+b}
的算术运算时,它将转换为{print expression%}
,但当它得到{var}
或{object attribute 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}}{{object.var}}{%print func()%}{%print
object.function()%}{%print a+b%}{%print“string”%%}{%print”{{{var}}}{%print
“function()”%}{%print“a+b”%}”
我想要的输出是:
{{var}}{{object.var}}{%print func()%}{%print
object.function()%}{%print a+b%}{{“string”}{{{{var}}}}{{“function()”
}}{{“a+b”}'
注意:这里的一个条件是介于{{}}
之间的表达式可以具有类似{{“string”}
的字符串表达式,即使用双引号或{“string”}
即使用单引号。code
为了更美观的打印,我只是去掉开头和结尾的空白。它也简化了正则表达式
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))
这大概是因为您在角色组中使用了
\w
。您可以使用\“
在那里添加双引号,或者不使用正则表达式测试”()“
是否在val.group(1)
(以及任何类似+-*/
)中。我不能只检查“()”这一点,因为我想转换类似于{a+b}的算术表达式,如果我要检查“()它还将转换类似{{“function()”}的表达式。我只想转换{{function()}}或{a+b}}而不是像{{“function()”}{{“a+b”}这样的表达式。也许最简单的方法是为周围的(双)引号或周围的双大括号添加大小写。或者找到一个模板转换器,它已经完成了您要做的事情。您的答案非常正确,但是在这个模式中,我们只能查找包含加法符号的算术表达式。我们不能只解析分式、乘法、模或除法{{a+b}将是{%print a+b%}而不是{a+b*c-d/100}或{1*2}或{20-10}等等,我们还想把它们转换成{%print算术运算%},除非它们不是像{1*2}之类的字符串。@yashlodha{a+b*c-d/100}
在我的解决方案中被转换为{%print a+b*c-d/100%}
您提到的另一个。字符串{{“1*2”}
被转换为{{“1*2”}。那么问题在哪里呢?{1*2}变成{%print 1*2%}或者{20/10}变成{%print 20/10%}或者{5-4}变成{%print 5-4%}。@yashlodha更新了我的答案,它现在可以用你的例子来回答了。变量名的语法是什么?也许可以在不通过语法定义的情况下替换\w,而且我必须确保如果我有{{“string”| filter}},它将更改为{%“string”| filter%}
{{ 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 %}