Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 正则表达式以排除表达式中的字符串和属性_Python_Regex_String_Algorithm - Fatal编程技术网

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 %}