再次发帖问:如何取出字符串中“(”和“)”之间的字符(100)

  • 主题发起人 主题发起人 chuanxue
  • 开始时间 开始时间
C

chuanxue

Unregistered / Unconfirmed
GUEST, unregistred user!
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1058291上面连接中有人提过,但方法不是很全。我想知道:如果字符串中有多个(),想分别得到()中的字符串怎么办?如果多个()镶嵌怎么办?(1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5))我想得到1+22+23+34+45+5我实际上每次只能得到1+2,而后面那个只得到空的。我想就是无法区分括号是每几个。
 
楼主到底是什么要求?比如 12345678(aaa(bbbbb(cccc(dddd)bbbbbb)aaa)12345你想得到什么结果?
 
这种问题貌似不难吧?
 
看一下 编译原理 语法分析
 
...implementation{$R *.dfm}function KH(const str:string;AKHRSeq:Integer):string;var i,iKHL,iKHR:Integer; KHLArr:array[0..99] of integer;//只处理不大于100个左括号begin iKHL:=0; iKHR:=0; result:=''; for i:=1 to length(str) do begin if str='(' then //遇到左括号,将左括号在字符串里的索引记录下来 begin KHLArr[iKHL]:=i; inc(iKHL); end else if str=')' then inc(iKHR); if (iKHR=AKHRSeq) and (iKHL>=iKHR) then begin result:=Copy(str,KHLArr[iKHL-iKHR]+1,i-KHLArr[iKHL-iKHR]-1); exit; end; end; if (iKHL=0) or (iKHR=0) then result:=str;end;procedure TForm1.Edit1Change(Sender: TObject);var i:integer; iKHR:Integer; str:string;begin str:=edit1.Text; if str='' then begin edit2.Clear; exit; end; if str[length(str)]=')' then begin iKHR:=1; for i:=length(str)-1 downto 1 do if str=')' then inc(iKHR); edit2.Text:=KH(str,iKHR); end else edit2.Text:=edit1.Text;end;end.
 
function TForm1.ParsePairOfDelimiter(const AStr: string; const APair1, APair2: Char; AList: TStringList; const IsIgnoreSpace: Boolean = True): Integer;var TmpStr: string; iPre, iEnd: Integer;begin Result := 0; iPre := 1; iEnd := Length(AStr); if iPre >= iEnd then Exit; TmpStr := AStr; iPre := Pos(APair1, TmpStr); iEnd := LastDelimiter(APair2, TmpStr); // 如果只有 APair1, 而没有成对的 APair2,则取 APair1 之后的所有字符串 // 如果要求 APair1, APair2 必须成对出现,则隐掉此句 if (iEnd = 0) and (iPre > 0) then iEnd := Length(TmpStr) + 1; while iPre < iEnd do begin TmpStr := Copy(TmpStr, iPre + 1, iEnd - iPre -1); if not IsIgnoreSpace or (TmpStr <> '') then begin Inc(Result); if AList <> nil then AList.Add(TmpStr); end; iPre := Pos(APair1, TmpStr); iEnd := LastDelimiter(APair2, TmpStr); // 如果只有 APair1, 而没有成对的 APair2,则取 APair1 之后的所有字符串 // 如果要求 APair1, APair2 必须成对出现,则隐掉此句 if (iEnd = 0) and (iPre > 0) then iEnd := Length(TmpStr) + 1; end;end;procedure TForm1.btn1Click(Sender: TObject);var list: TStringList;begin list := TStringList.Create; try if ParsePairOfDelimiter(edt1.Text, '(', ')', list) > 0 then Memo1.Lines := list; finally list.Free; end;end;
 
wangdonghai的方法只能得到1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5)而liulsr的方法只能得到1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5)2+2)+(3+3)+(4+4)+(1+(5+53+3)+(4+4中间部分怎么处理?
 
你是想输入完整串字符串后再将这个字符串解析出来呢,还是一边输入一边解析呢,我是一边输入一边解析,你在edit1里输入2楼给的字符串试一下,你一开始给的问题没有描述清楚
 
唉,有那么复杂吗?LZ,你的要求确实是取类似于(1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5))这样的字符串为如下内容吗?1+22+23+34+45+5如果是,就试试下面的代码:procedure TForm1.btn1Click(Sender: TObject);var StrList: TStringList; I: Integer;begin try StrList := TStringList.Create; // 把源字符串中的 ( 与 ) 替换成回车换行符后存入一个 TStringList 中 StrList.Text := StringReplace(StringReplace('(1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5))', '(', #13#10, [rfReplaceAll]), ')', #13#10, [rfReplaceAll]); for I := 0 to StrList.Count - 1 do // 循环取数 if Length(StrList.Strings) > 2 then // 条件可以自定义 lst1.Items.Add(StrList.Strings); // 结果放到一个 TListBox 中 finally StrList.Free; end;end;注意一点:此代码忽略了字符串最后的(1+(5+5))部分地1+,只得到了5+5(根据条件中的长度大于2)。个人觉得你这个设计或需求很怪(这不是一个好方法),建议你调整一下。
 
...procedure KH(const str:string;AStrings:TStrings);var i,iStart:integer;begin AStrings.Clear; iStart:=-1; for i:=1 to length(str) do begin if str='(' then iStart:=i else if (str=')') and (iStart>0) then begin AStrings.Add(Copy(str,iStart+1,i-iStart-1)); iStart:=-1; end; end;end;//memo1:TMemo;procedure TForm1.Button1Click(Sender: TObject);begin KH(edit1.Text,memo1.Lines)end;
 
procedure TForm1.SpeedButton2Click(Sender: TObject);var i, j, k : integer; st : string;begin Memo_mc.Clear; st:='(1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5))'; Memo_mc2.Lines.Add(st); i:=pos(')', st); while i>0 do begin k:=0; for j:=i downto 1 do begin if st[j]='(' then begin k:=1; break; end; end; if k=1 then begin Memo_mc2.Lines.Add(Copy(st, j+1, i-1-j)); delete(st, j, i-j+1); //Memo_mc2.Lines.Add(st); end else delete(st, i, 1); i:=pos(')', st); end; exit;end;
 
更简单的代码是ExtractStrings(['(', ')'], ['+'], '(1+2)+(2+2)+(3+3)+(4+4)+(1+(5+5))', lst1.Items);你可以试试效果。
 
谢谢各位。我主要想做一个计算表达式的计算器。在计算角度与弧度时括号内的值取不出来。现在好了。
 
那就结贴吧。
 
我上次分配分数,以为结了。结果还没结。不好意思。
 
后退
顶部