我遇到一个问题,如果我从文件中得到几个方程式,例如:
na = 1.350
Lambda = 0.2
Seg = 2*na*Lambda
mag = 4
result = mag+Seg*3
如何获得结果的真实价值?谢谢!
答案 0 :(得分:3)
嗯,你需要的是一点点解析和一点点映射,当然还有eval
的创造性使用。
# Assume that the contents of the file is in a big string, $equations
array set vars {}
set map {}
foreach line [split $equations "\n"] {
if {![regexp {^ *(\w+) *= *(.*)$} $line -> var exp]} {
error "illegal line '$line'"
}
set vars($var) [expr [string map $map $exp]]
puts "computed $var as $vars($var)"
lappend map $var \$vars($var)
}
puts "result = $vars(result)"
现在关键点是:
regexp {^ *(\w+) *= *(.*)$} $line -> var exp
解析一行以提取变量,并解析要计算的表达式以获取变量的值。
expr [string map $map $exp]
应用当前映射将$exp
转换为Tcl表达式,并将结果计算为表达式。 (正式不安全,但真的方便!)
lappend map $var \$vars($var)
更新映射转换以了解如何读取适当的变量。基本上,Lambda
在将来的表达式中将变为$vars(Lambda)
。
答案 1 :(得分:1)
Donal Fellows的解决方案非常出色(可能需要注意的是,作为另一个标识符的子字符串的标识符可能会有问题),但还有更多方法可以做到这一点:
set equations {
na = 1.350
Lambda = 0.2
Seg = 2*na*Lambda
mag = 4
result = mag+Seg*3
}
将这组方程转换为带有标识符键的字典:
% set expressions [dict create {*}[string map {= { }} $equations]]
na 1.350 Lambda 0.2 Seg 2*na*Lambda mag 4 result mag+Seg*3
在字典值中,将美元符号添加到所有标识符(假设所有字符串仅包含字母字符)
dict for {ident expr} $expressions {
dict set expressions $ident [regsub -all {([[:alpha:]]+)} $expr {$\1}]
}
连续创建与标识符对应的变量,其值根据表达式计算:
dict for {ident expr} $expressions {
upvar 0 $ident var
set var [expr $expr]
}
puts "Result: $result"
为简洁起见,这些步骤当然可以合并:
dict for {ident expr} [dict create {*}[string map {= { }} $equations]] {
upvar 0 $ident var
set var [expr [regsub -all {([[:alpha:]]+)} $expr {$\1}]]
}
文档: dict, expr, puts, regsub, set, string, upvar, {*} (syntax), Syntax of Tcl regular expressions