扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
eval能解决的事情,直接写PHP代码肯定一样能解决,因为eval() 作用就是把字符串按照
目前成都创新互联已为成百上千的企业提供了网站建设、域名、雅安服务器托管、网站运营、企业网站设计、武胜网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
PHP
代码来计算,但是有些场景下有这个解决手段能让你事半功倍,为什么要去绕路呢?
举个栗子我数据库里存储了用户输入的公式,1+1-2*3/2,如果没有eval能想象到要解决这个公式计算得写一大段函数来实现,但现在我们只要
1eval('return 1+1-2*3/2;')
就搞定了,你说用PHP代码行吗?行!但是何苦呢?
package mathTools;
/**
* Eval.java
*
* Created on 2006年4月10日, 下午3:46
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*
* 支持运算符:+ - * / % ] [ ! | =
* 其中:
* ] 表示大于等于
* [ 表示小于等于
* ! 表示不等于
* | 表示或
* & 表示与
* = 表示是否等于
*
* 支持函数:sqrt,square,ceil,sin,cos,asin,acon.tan.atan,log,exp 具体含义见 calFunction 代码
*
*/
/**
*
* @author Trumplet
*
*/
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Eval{
public static String OPTS="+-*/%][!|=#";
public Object calculate(String expression) throws ExpressionException{
try {
Stack Opts=new Stack();
Stack Values=new Stack();
String exp=expression+"#";
int nCount=exp.length(),nIn,nOut,nTemp;
Opts.push("#");
String temp="",optOut="",optIn="",value1="",value2="",optTemp="",opt="",temp1="";
int nFun=0;
boolean isFun=false;
for(int i=0;inCount;){
nTemp=0;
opt=exp.substring(i,i+1);
isFun=false;
temp1="";
while(inCount){
if(!temp1.equals("")){
if(opt.equals("(")){
nFun++;
isFun=true;
} else if(opt.equals(")")){
nFun--;
}
}
if((nFun0)||((!isFun)this.isValue(opt))){
temp1+=opt;
nTemp++;
opt=exp.substring(i+nTemp,i+nTemp+1);
} else{
if(isFun){
temp1+=opt;
nTemp++;
}
break;
}
}
if(temp1.equals("")){
temp=opt;
} else{
temp=temp1;
}
if(nTemp0){
i=i+nTemp-1;
}
temp=temp.trim();
if(this.isValue(temp)){
temp=this.getValue(temp);
Values.push(temp);
i++;
} else{
optIn=Opts.pop().toString();
nIn=this.getOptPriorityIn(optIn);
nOut=this.getOptPriorityOut(temp);
if(nIn==nOut){
i++;
} else if(nInnOut){
String ret="";
value1=Values.pop().toString();
value2=Values.pop().toString();
ret=String.valueOf(this.calValue(value2,optIn,value1));
Values.push(ret);
} else if(nInnOut){
Opts.push(optIn);
Opts.push(temp);
i++;
}
}
}
return Values.pop();
} catch(ExpressionException eE) {
throw eE;
} catch(Exception e) {
throw new ExpressionException("表达式"+expression+"格式非法!");
}
}
protected int getOptPriorityOut(String opt)throws ExpressionException{
if(opt.equals("+")){
return 1;
} else if(opt.equals("-")){
return 2;
} else if(opt.equals("*")){
return 5;
} else if(opt.equals("/")){
return 6;
} else if(opt.equals("%")){
return 7;
} else if(opt.equals("")){
return 11;
} else if(opt.equals("")){
return 12;
} else if(opt.equals("]")){
return 13;
} else if(opt.equals("[")){
return 14;
} else if(opt.equals("!")){
return 15;
} else if(opt.equals("|")){
return 16;
} else if(opt.equals("")) {
return 23;
} else if(opt.equals("=")) {
return 25;
} else if(opt.equals("#")) {
return 0;
} else if(opt.equals("(")){
return 1000;
} else if(opt.equals(")")){
return -1000;
}
throw new ExpressionException("运算符"+opt+"非法!");
}
protected int getOptPriorityIn(String opt) throws ExpressionException{
if(opt.equals("+")){
return 3;
} else if(opt.equals("-")){
return 4;
} else if(opt.equals("*")){
return 8;
} else if(opt.equals("/")){
return 9;
} else if(opt.equals("%")){
return 10;
} else if(opt.equals("")){
return 17;
} else if(opt.equals("")){
return 18;
} else if(opt.equals("]")){
return 19;
} else if(opt.equals("[")){
return 20;
} else if(opt.equals("!")){
return 21;
} else if(opt.equals("|")){
return 22;
} else if(opt.equals("")) {
return 24;
} else if(opt.equals("=")) {
return 26;
} else if(opt.equals("(")){
return -1000;
} else if(opt.equals(")")){
return 1000;
} else if(opt.equals("#")){
return 0;
}
throw new ExpressionException("运算符"+opt+"非法!");
}
protected String getOPTS() {
return OPTS;
}
protected boolean isValue(String cValue){
String notValue=this.getOPTS()+"()";
return notValue.indexOf(cValue)==-1;
}
protected boolean isOpt(String value){
return this.getOPTS().indexOf(value)=0;
}
protected double calValue(String value1,String opt,String value2) throws ExpressionException{
try {
double dbValue1=Double.valueOf(value1).doubleValue();
double dbValue2=Double.valueOf(value2).doubleValue();
long lg=0;
if(opt.equals("+")){
return dbValue1+dbValue2;
} else if(opt.equals("-")){
return dbValue1-dbValue2;
} else if(opt.equals("*")){
return dbValue1*dbValue2;
} else if(opt.equals("/")){
return dbValue1/dbValue2;
} else if(opt.equals("%")){
lg=(long)(dbValue1/dbValue2);
return dbValue1-lg*dbValue2;
} else if(opt.equals("")){
if(dbValue1dbValue2)
return 1;
else
return 0;
} else if(opt.equals("")){
if(dbValue1dbValue2)
return 1;
else
return 0;
} else if(opt.equals("]")){
if(dbValue1=dbValue2)
return 1;
else
return 0;
} else if(opt.equals("[")){
if(dbValue1=dbValue2)
return 1;
else
return 0;
} else if(opt.equals("!")){
if(dbValue1!=dbValue2)
return 1;
else
return 0;
} else if(opt.equals("|")){
if(dbValue10||dbValue20)
return 1;
else
return 0;
} else if(opt.equals("")){
if(dbValue10dbValue20)
return 1;
else
return 0;
} else if(opt.equals("=")){
if(dbValue1==dbValue2)
return 1;
else
return 0;
}
}catch(Exception e) {
throw new ExpressionException("值"+value1+"或"+value2+"在进行"+ opt+"运算时非法!");
}
throw new ExpressionException("运算符"+opt+"非法!");
}
protected String getValue(String oldValue) throws ExpressionException{
String reg="^([a-zA-Z0-9_]+)\\(([a-zA-Z0-9_.()]+)\\)$";
if(this.isFunctionCal(oldValue)){
Pattern p=Pattern.compile(reg);
Matcher m=p.matcher(oldValue);
m.find();
return calFunction(m.group(1),m.group(2));
}
return oldValue;
}
protected boolean isFunctionCal(String value){
String reg="^([a-zA-Z0-9_]+)\\(([a-zA-Z0-9_.()]+)\\)$";
return value.matches(reg);
}
protected String calFunction(String function,String value) throws ExpressionException{
String lowerFun=function.toLowerCase();
double db=0;
try {
db=Double.valueOf(this.getValue(value)).doubleValue();
if(lowerFun.equals("log")){
return String.valueOf(Math.log(db));
} else if(lowerFun.equals("square")){
return String.valueOf(Math.pow(db,2));
} else if(lowerFun.equals("sqrt")){
return String.valueOf(Math.sqrt(db));
} else if(lowerFun.equals("sin")){
return String.valueOf(Math.sin(db));
} else if(lowerFun.equals("asin")){
return String.valueOf(Math.asin(db));
} else if(lowerFun.equals("cos")){
return String.valueOf(Math.cos(db));
} else if(lowerFun.equals("tan")){
return String.valueOf(Math.tan(db));
} else if(lowerFun.equals("atan")){
return String.valueOf(Math.atan(db));
} else if(lowerFun.equals("ceil")){
return String.valueOf(Math.ceil(db));
} else if(lowerFun.equals("exp")){
return String.valueOf(Math.exp(db));
}
}catch(Exception e) {
throw new ExpressionException("函数"+function+"值"+value+"非法!");
}
throw new ExpressionException("函数"+function+"不支持!");
}
public static void main(String[]args) {
Eval be=new Eval();
//String exp="sin(ceil(100))*29+20+30*3+0|0|1+11*5+2=2";
//String exp="sin(ceil(sqrt(100)))*29+20+30*3+0|0|1+11*5+2=2";
String exp="8/(3-8/3)";
try {
System.out.println(be.calculate(exp));
} catch(ExpressionException eE) {
System.out.println(eE.getMessage());
}
}
//表达式异常类代码:
public class ExpressionException extends Exception{
public ExpressionException(String msg) {
super(msg);
}
}
}
1、列表解析(数据量少)
[i for i in range(10)]
2、生成器(可迭代对象)表达式(数据量大)
生成器自动是实现迭代器协议(next方法),用next取值后,该值不会再产生了,省内存。
( i for i in range(10) )
2、生成器函数
yield:yield 1 相当于return返回值,但可以执行多次;x=yield保留函数运行状态; 接受send 传过来的值复制给x,若没有send返回none。
send可以使生成器接着运行(有点像next),generator.send(none):send把none传给yield,进行触发。
def test():
yield 1
yield 2
yield 3
response=test() #拿到生成器,response为生成器对象。
执行:print( response.__next__() )
3、生成器函数深入
例1
(1)、def product_baozi():
re=[ ]
for i in range(10):
re.append("baozi%s" %i)
return re
(2)def product_baozi():
for i in range(10): #循环生成列表
yield "baozi%s" %i
pro_g=product_baozi() #生成器对象
#取值
for i in pro_g:
print(i)
或者:baozi=pro_g.__next__() #一个一个取值
注意:(2)的效率比(1)高,省内存,保留函数运行状态(状态挂起);生成器只能遍历一次
例2
def get_population():
with open ("人口普查",“r”encoding=‘utf-8’) as f:
yield i
data=get_population() #可迭代对象,只能迭代一次
#求和
ret=0
for p in data: #相当与data.__next__() (next(t))
p_dict=eval(p) #转成字典
ret+=p_dict[ 'population ' ]
或者:all_population=sum(eval(i)['population'] for i in data) #sum(可迭代对象)
#比例
for i in data: #注意data中的值被使用完了
rate= eval(i)['population'] / all_population
注意:evel:把字符串里面的数据类型提取出来,字符串里面的表达式运算出来
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流