type TToken=record strName:string; strValue:string; end;const TokenCnt = 4; strToken:array[0..TokenCnt-1] of TToken=( (strName:'a1';strValue:'1'), (strName:'a11';strValue:'2'), (strName:'a12';strValue:'3'), (strName:'b1';strValue:'a122') );///////////所有替换的变量,值在这里定义。.......procedure TForm1.Button1Click(Sender: TObject); var i:integer; strTemp:string; begin strTemp:=Edit1.Text; for i:=0 to TokenCnt-1 do begin strTemp:=StringReplace(strTemp,strToken[i].strName,strToken[i].strValue,[rfReplaceAll]); end; Label1.Caption:=strTemp; end;
to gzmhero(hihihi) 我看了一下,这么做是不对的,出来的结果是 1+a122+11*12因为把a12当成了a1和2,
刚才的替换,如果有变量名称部分重复的是会出现这个问题的。 给你写个递归替换: TToken=record strName:string; strValue:string; end;const TokenCnt = 4; strToken:array[0..TokenCnt-1] of TToken=( (strName:'a1';strValue:'1'), (strName:'a11';strValue:'2'), (strName:'a12';strValue:'3'), (strName:'b1';strValue:'a122') ); strOper:set of char=['+','-','*','/'];function AStringReplace(strOld:string):string; var i:integer; strValue:string; begin strValue:=''; for i:=0 to TokenCnt-1 do if strOld=strToken[i].strName then strValue:=strToken[i].strValue; Result:=strValue; end;function MyReplace(strTemp:string):string; var strVar:string; strValue:string; i:integer; begin strVar:=''; strValue:=''; for i:=1 to Length(strTemp) do begin if (strTemp[i] in strOper) then begin strVar:=AStringReplace(strVar); strValue:=strVar+strTemp[i]+MyReplace(Copy(strTemp,i+1,length(strTemp))); break; end else strVar:=strVar+strTemp[i]; end; if strValue='' then strValue:=AStringReplace(strTemp); Result:=strValue; end;procedure TForm1.Button1Click(Sender: TObject); var i:integer; strTemp:string; begin strTemp:=Edit1.Text; strTemp:=MyReplace(strTemp); Label1.Caption:=strTemp; end;
在楼上的基础上加了点 function TForm1.ChangeStr(str: string): string; var s: string; splitcount: integer; i,j: integer; splitPosition: TStringList; tempstr:string; ParamSet: array of string; splitSet: array of string; begin try splitPosition:=TStringList.Create; splitPosition.clear; splitPosition.add('0'); s:= str; splitCount:=0; i:=0;j:=0; for i:=0 to length(str)-1 do begin if s[i] in split_set then begin inc(splitcount); splitPosition.add(inttostr(i)); end; end; setlength(splitSet,splitcount); setlength(ParamSet,splitcount+1); i:=0; j:=0; for i:=0 to splitPosition.count-2 do begin ParamSet[j]:=copy(s,strtoint(splitPosition.Strings[i])+1,strtoint(splitPosition.Strings[i+1])-strtoint(splitPosition.Strings[i])-1); splitSet[j]:=copy(s,strtoint(splitPosition.Strings[i+1]),1); inc(j); end; i:=splitPosition.count-2; paramSet[j]:=copy(s,strtoint(splitPosition.Strings[i+1])+1,length(s)-strtoint(splitPosition.Strings[i+1])); j:=0; i:=0; for j:=0 to splitcount do begin for i:=0 to TokenCnt-1 do begin if paramSet[j]=strToken[i].strName then paramSet[j]:=strToken[i].strValue; end; end; i:=0; for i:=0 to splitcount-1 do begin result:=Result+paramSet[i]+splitSet[i]; end; result:=Result+paramSet[i]; finally splitPosition.free; splitSet:=nil; ParamSet:=nil; end; end;
aloking(黑鲸) 的代码看得我头都大了, 汗 多谢两位
ParamSet: array of string; splitSet: array of string; 先分析这个计算式 计算 paramset 和splitset的个数,记录splitset的postion;用paramset存 a1,b1,a11,a12; splitSet存+,-,*,%paramset数比splitset多1个,呵呵,完全是偷懒的 接下来,替换掉paramset里面的东西 再组合成新的表达式 原来想着会比gzmhero(hihihi) 代码要短,写下来才知道, 顺手写的,不过我贴过来代码,怎么统一都对齐了,看了我自己都头晕了
没那么复杂: use Comobj; ...procedure TForm1.Button1Click(Sender: TObject); var jg:string; vScript: Variant; begin vScript:=CreateOleObject('ScriptControl'); vScript.Language := 'VBScript'; jg:=vScript.Eval('3+4*5'); showmessage(jg); end;
/////////////如果是变量替换,修改一下,下面的代码可以。有数学函数也没关系。 type TToken=record strName:string; strValue:string; end;const TokenCnt = 4; strToken:array[0..TokenCnt-1] of TToken=( (strName:'a1';strValue:'1'), (strName:'a11';strValue:'2'), (strName:'a12';strValue:'3'), (strName:'b1';strValue:'a122') ); strOper:set of char=['+','-','*','/','(',')'];function AStringReplace(strOld:string):string; var i:integer; strValue:string; begin strValue:=strOld; for i:=0 to TokenCnt-1 do if strOld=strToken[i].strName then strValue:=strToken[i].strValue; Result:=strValue; end;function MyReplace(strTemp:string):string; var strVar:string; strValue:string; i:integer; begin strVar:=''; strValue:=''; for i:=1 to Length(strTemp) do begin if (strTemp[i] in strOper) then begin strVar:=AStringReplace(strVar); strValue:=strVar+strTemp[i]+MyReplace(Copy(strTemp,i+1,length(strTemp))); break; end else strVar:=strVar+strTemp[i]; end; if strValue='' then strValue:=AStringReplace(strTemp); Result:=strValue; end;procedure TForm1.Button1Click(Sender: TObject); var i:integer; strTemp:string; begin strTemp:=Edit1.Text; strTemp:=MyReplace(strTemp); Label1.Caption:=strTemp; end;
TToken=record
strName:string;
strValue:string;
end;const
TokenCnt = 4;
strToken:array[0..TokenCnt-1] of TToken=(
(strName:'a1';strValue:'1'),
(strName:'a11';strValue:'2'),
(strName:'a12';strValue:'3'),
(strName:'b1';strValue:'a122')
);///////////所有替换的变量,值在这里定义。.......procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
strTemp:string;
begin
strTemp:=Edit1.Text;
for i:=0 to TokenCnt-1 do
begin
strTemp:=StringReplace(strTemp,strToken[i].strName,strToken[i].strValue,[rfReplaceAll]);
end;
Label1.Caption:=strTemp;
end;
给你写个递归替换: TToken=record
strName:string;
strValue:string;
end;const
TokenCnt = 4;
strToken:array[0..TokenCnt-1] of TToken=(
(strName:'a1';strValue:'1'),
(strName:'a11';strValue:'2'),
(strName:'a12';strValue:'3'),
(strName:'b1';strValue:'a122')
);
strOper:set of char=['+','-','*','/'];function AStringReplace(strOld:string):string;
var
i:integer;
strValue:string;
begin
strValue:='';
for i:=0 to TokenCnt-1 do
if strOld=strToken[i].strName then
strValue:=strToken[i].strValue;
Result:=strValue;
end;function MyReplace(strTemp:string):string;
var
strVar:string;
strValue:string;
i:integer;
begin
strVar:='';
strValue:='';
for i:=1 to Length(strTemp) do
begin
if (strTemp[i] in strOper) then
begin
strVar:=AStringReplace(strVar);
strValue:=strVar+strTemp[i]+MyReplace(Copy(strTemp,i+1,length(strTemp)));
break;
end else
strVar:=strVar+strTemp[i];
end;
if strValue='' then
strValue:=AStringReplace(strTemp);
Result:=strValue;
end;procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
strTemp:string;
begin
strTemp:=Edit1.Text;
strTemp:=MyReplace(strTemp);
Label1.Caption:=strTemp;
end;
function TForm1.ChangeStr(str: string): string;
var
s: string;
splitcount: integer;
i,j: integer;
splitPosition: TStringList;
tempstr:string;
ParamSet: array of string;
splitSet: array of string;
begin
try
splitPosition:=TStringList.Create;
splitPosition.clear;
splitPosition.add('0');
s:= str;
splitCount:=0;
i:=0;j:=0;
for i:=0 to length(str)-1 do
begin
if s[i] in split_set then
begin
inc(splitcount);
splitPosition.add(inttostr(i));
end;
end;
setlength(splitSet,splitcount);
setlength(ParamSet,splitcount+1);
i:=0;
j:=0;
for i:=0 to splitPosition.count-2 do
begin
ParamSet[j]:=copy(s,strtoint(splitPosition.Strings[i])+1,strtoint(splitPosition.Strings[i+1])-strtoint(splitPosition.Strings[i])-1);
splitSet[j]:=copy(s,strtoint(splitPosition.Strings[i+1]),1);
inc(j);
end;
i:=splitPosition.count-2;
paramSet[j]:=copy(s,strtoint(splitPosition.Strings[i+1])+1,length(s)-strtoint(splitPosition.Strings[i+1]));
j:=0;
i:=0;
for j:=0 to splitcount do
begin
for i:=0 to TokenCnt-1 do
begin
if paramSet[j]=strToken[i].strName then paramSet[j]:=strToken[i].strValue;
end;
end;
i:=0;
for i:=0 to splitcount-1 do
begin
result:=Result+paramSet[i]+splitSet[i];
end;
result:=Result+paramSet[i];
finally
splitPosition.free;
splitSet:=nil;
ParamSet:=nil;
end;
end;
汗
多谢两位
splitSet: array of string;
先分析这个计算式
计算 paramset 和splitset的个数,记录splitset的postion;用paramset存 a1,b1,a11,a12;
splitSet存+,-,*,%paramset数比splitset多1个,呵呵,完全是偷懒的
接下来,替换掉paramset里面的东西
再组合成新的表达式 原来想着会比gzmhero(hihihi) 代码要短,写下来才知道,
顺手写的,不过我贴过来代码,怎么统一都对齐了,看了我自己都头晕了
use Comobj;
...procedure TForm1.Button1Click(Sender: TObject);
var jg:string;
vScript: Variant;
begin
vScript:=CreateOleObject('ScriptControl');
vScript.Language := 'VBScript';
jg:=vScript.Eval('3+4*5');
showmessage(jg);
end;
那就有问题了,如果在加上sin等数学函数呢?
type
TToken=record
strName:string;
strValue:string;
end;const
TokenCnt = 4;
strToken:array[0..TokenCnt-1] of TToken=(
(strName:'a1';strValue:'1'),
(strName:'a11';strValue:'2'),
(strName:'a12';strValue:'3'),
(strName:'b1';strValue:'a122')
);
strOper:set of char=['+','-','*','/','(',')'];function AStringReplace(strOld:string):string;
var
i:integer;
strValue:string;
begin
strValue:=strOld;
for i:=0 to TokenCnt-1 do
if strOld=strToken[i].strName then
strValue:=strToken[i].strValue;
Result:=strValue;
end;function MyReplace(strTemp:string):string;
var
strVar:string;
strValue:string;
i:integer;
begin
strVar:='';
strValue:='';
for i:=1 to Length(strTemp) do
begin
if (strTemp[i] in strOper) then
begin
strVar:=AStringReplace(strVar);
strValue:=strVar+strTemp[i]+MyReplace(Copy(strTemp,i+1,length(strTemp)));
break;
end else
strVar:=strVar+strTemp[i];
end;
if strValue='' then
strValue:=AStringReplace(strTemp);
Result:=strValue;
end;procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
strTemp:string;
begin
strTemp:=Edit1.Text;
strTemp:=MyReplace(strTemp);
Label1.Caption:=strTemp;
end;
str:='a*(b-c)';
D如何用str的计算式.楼主很像知道http://community.csdn.net/Expert/topic/3913/3913938.xml?temp=.5002252
楼主能帮忙吗?