# -*- coding:utf8 -*- import re class ConvertException(Exception): pass class ArgsConvert(object): def __init__(self,preString,subfixString,coding='utf-8'): self.preString = preString self.subfixString = subfixString self.coding=coding sl1 = [ u'\\' + c for c in self.preString ] sl2 = [ u'\\' + c for c in self.subfixString ] ps = u''.join(sl1) ss = u''.join(sl2) re1 = ps + r"[_a-zA-Z_\u4e00-\u9fa5][a-zA-Z_0-9\u4e00-\u9fa5\,\.\'\{\}\[\]\(\)\-\+\*\/]*" + ss self.re1 = re1 # print( self.re1,len(self.re1),len(re1),type(self.re1)) async def convert(self,obj,namespace,default=''): """ obj can be a string,[],or dictionary """ if type(obj) == type(b''): return await self.convertBytes(obj,namespace,default) if type(obj) == type(''): return await self.convertString(obj,namespace,default) if type(obj) == type([]): ret = [] for o in obj: ret.append(await self.convert(o,namespace,default)) return ret if type(obj) == type({}): ret = {} for k in obj.keys(): ret.update({k:await self.convert(obj.get(k),namespace,default)}) return ret # print( type(obj),"not converted") return obj def findAllVariables(self,src): r = [] for ph in re.findall(self.re1,src): dl = self.getVarName(ph) r.append(dl) return r def getVarName(self,vs): return vs[len(self.preString):-len(self.subfixString)] async def getVarValue(self,var,namespace,default): v = default try: v = eval(var,namespace) except Exception as e: v = namespace.get(var, None) if v: return v if callable(default): return await default(var) return default return v async def convertString(self,s,namespace,default): args = re.findall(self.re1,s) for arg in args: dl = s.split(arg) var = self.getVarName(arg) v = await self.getVarValue(var,namespace,default) if type(v) != type(u''): v = str(v) s = v.join(dl) return s if __name__ == '__main__': from appPublic.asynciorun import run async def main(): ns = { 'a':12, 'b':'of', 'c':'abc', u'是':'is', 'd':{ 'a':'doc', 'b':'gg', } } AC = ArgsConvert('%{','}%') s1 = "%{a}% is a number,%{d['b']}% is %{是}% undefined,%{c}% is %{d['a']+'(rr)'}% string" arglist=['this is a descrciption %{b}% selling book',123,'ereg%{a}%,%{c}%'] argdict={ 'my':arglist, 'b':s1 } print(s1,'<=>',await AC.convert(s1,ns)) print(argdict,'<=>',await AC.convert(argdict,ns)) run(main)