我正在尝试在字符串中使用遵循特定格式的单词来创建一些变量。
例如,我的原始字符串是:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="workingTA" cols="35"></textarea>
我已经创建了如下词典:
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'
我要创建的函数是将@ Cost1(例如)替换为:
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
,以便我可以将字符串中的@视为变量的标记,并在字典中查找值。
因此,我的目的是:
mydict.get('Cost1')
->替换@@,使用string.replace()函数非常简单mydict.get('
–>我很难实现这一点我当时正在考虑for循环,但是在每个单词的末尾都带有@的逻辑后面加了“')”。也考虑过发电机,但不太确定
此外,我想添加一个检查以确保每个@ Cost1,@ Cost2等都在我的词典中,但是我应该能够做到这一点。
欢迎对此提供任何帮助
谢谢!
埃里克
编辑:
在您发表评论之后,我希望最终输出为:
')
答案 0 :(得分:3)
我认为您需要捕获一个正则表达式@
+字母/数字/下划线,即"@(\w+)
(匹配@
然后是1个或多个字母/数字/下划线并创建一个正则表达式分组给那些替换功能
import re
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'
expression = re.sub("@(\w+)",lambda m : str(mydict.get(m.group(1),0)),string)
结果:
'10 + (5 + 1) / 10 * 1.2'
此方法非常高效,因为它使用字典查找而不是循环替换和创建与变量一样多的字符串。
请注意,任何未知变量的结果均为0。如果您不希望使用该变量,请使用mydict[m.group(1)]
来触发键错误。
lambda
也不是强制性的。您可以编写一个实函数,只要它以match
对象作为输入并返回一个字符串作为输出即可。
def repfunc(m)
return str(mydict.get(m.group(1),0))
re.sub("@(\w+)",repfunc,string)
(这就是我们在获取值后转换为字符串的原因)
一旦有了该表达式,就可以应用一个评估器(eval
是最简单但不太安全的评估,ast.literal_eval
将不起作用,因为它不支持运算,但是还有其他运算符,例如simpleeval
第三方模块(可以向其提供一系列变量,从而进一步简化答案),或此处的其他示例:Evaluating a mathematical expression in a string)
答案 1 :(得分:1)
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
string = string.replace('@', '')
for i in mydict:
string = string.replace(i, str(mydict[i]))
print(string)
print(eval(string))
输出:
10 + (5 + 1) / 10 * 1.2
10.72