我想要实现如下功能,请问高手应该要怎么弄
有3个memo,其中memo1是用来读取文本的,内容有A,B字段(如a123b111)
memo2用来存取a...字段
memo3用来存取b...字段
请问如何在memo1中将a...b...区分开?并分别存取?谢谢!

解决方案 »

  1.   

    你这AB字段是什么意思?如果是指从数据表中读取的字段,可以用memo2和memo3分别从数据表中读取;如果是指一些包含ab字母的文本,可以用copy语句分别截取文本的内容,示例如下:var
      s:string;
    begin
      s:='a123b111';
      memo2.text:=copy(s,1,4);
      memo3.text:=copy(s,5,4);
    end;
      

  2.   

    楼主似乎没有描述清楚.
    你要取的A字段.如果是说包含A的字段.那是以什么结束的?还是说从头开始遇到A就结束.
    B字段一样..
    例如,有字符串:111a222b333c444a
    那按你说的memo1 := '111a222b' ?
             memo2 := '111a' ?
             memo3 := '222b' ?
    是这样?
      

  3.   

    都是与A或B开头的,但是A或B后面跟的数字长度不确定
    就是说要将A与B,B到A之间的字符取出来
    如memo1为
    a123777b66
    a456b555
    b333
    memo2里面就为
    a123777
    a456
    memo3里面就为
    b66
    b555
    b333
      

  4.   

    定义几个变量,再利用copy和pos分割字符
    var 
      s,s1,s2:string;
     
    begin 
      s:=memo1.text; 
    while((pos('a',s)>0)||(pos('b',s)>0))
    begin
      s1:=s1+copy(s,1,pos('a',s)-1);
      s:=copy(s,pos('a',s)+1,length(s));
      s2:=s2+copy(s,1,pos('b',s)-1);
      s:=copy(s,pos('b',s)+1,length(s));
    end;
      memo2.text:=s1;
      memo3.text:=s2;
    end;
      

  5.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
        i,posA,posB,myPos : integer;
        tmpStr,leftStr : string;
    begin
        memo2.Clear;
        memo3.Clear;
        for i := 0 to Memo1.Lines.Count - 1 do begin
            tmpStr := trim(memo1.Lines[i]);
            posA := pos('a',tmpStr);
            posB := pos('b',tmpStr);        while ((posA = 1) or (posB = 1)) do begin
                if posA = 1 then begin
                    leftStr := copy(tmpStr,2,length(tmpStr));
                    posA := pos('a',leftStr);
                    posB := pos('b',leftStr);                myPos := 0;
                    if posa > 0 then myPos := posa;
                    if posB > 0 then begin
                        if myPos = 0 then myPos := posB
                        else myPos := min(myPos,posB);
                    end;                if myPos = 0 then begin
                        Memo2.Lines.Add(tmpStr);
                        break;   
                    end
                    else begin
                        Memo2.Lines.Add(copy(tmpStr,1,myPos));
                        tmpStr := trim(copy(leftStr,myPos,length(tmpStr)));
                        posA := pos('a',tmpStr);
                        posB := pos('b',tmpStr);
                        continue;
                    end;
                end ;
                if posB = 1 then begin
                    leftStr := copy(tmpStr,2,length(tmpStr));
                    posA := pos('a',leftStr);
                    posB := pos('b',leftStr);                myPos := 0;
                    if posa > 0 then myPos := posa;
                    if posB > 0 then begin
                        if myPos = 0 then myPos := posB
                        else myPos := min(myPos,posB);
                    end;                if myPos = 0 then begin
                        Memo3.Lines.Add(tmpStr);
                        break;  
                    end
                    else begin
                        Memo3.Lines.Add(copy(tmpStr,1,myPos));
                        tmpStr := trim(copy(leftStr,myPos,length(tmpStr)));
                        posA := pos('a',tmpStr);
                        posB := pos('b',tmpStr);
                        continue;
                    end;
                end;
            end;
        end;
    end;
      

  6.   

    先谢谢两位的帮助,我今天测试了一下,问题如下:
    wanglaibing大哥的
    while((pos('a',s)>0)||(pos('b',s)>0)) 的在||中间报错....我不知道要怎么修改;
    pecknic老兄的
    在else myPos := min(myPos,posB);行中min处报错,我把空格删掉了还是不行.
    谢谢各位帮忙.
    这个问题还没有解决,我用的是DELPHI7写的程序
      

  7.   

    下面是一个取巧的方法:
      利用了StringReplace函数和StringList的CommaText属性进行处理,这种方式不一定比直接扫描字符串来的快,但是看起来代码还是比较简洁的,呵呵,复杂的地方都被StringReplace函数和StringList的CommaText属性所隐藏了
    var
      sl: TStringList;
      s: AnsiString;
      I: Integer;
    begin
      sl := TStringList.Create;
      try
        s := Memo1.Text;
        s := StringReplace(s, #13#10, '', [rfReplaceAll]);//去掉换行
        s := StringReplace(s, 'a', ',a', [rfReplaceAll]); //将a开头的字段替换成带 ,a
        s := StringReplace(s, 'b', ',b', [rfReplaceAll]); //将a开头的字段替换成带 ,b
        sl.CommaText := s;  //CommaText会自动以 , 分割字符串,每个 , 分割的字符串是一行
        Memo2.Clear;
        Memo3.Clear;
        for I := 0 to sl.Count - 1 do
        begin
          if sl[I] <> '' then
          begin
            case sl[I][1] of
              'a': Memo2.Lines.Add(sl[I]);
              'b': Memo3.Lines.Add(sl[I]);
            end;
          end;
        end;
      finally
        sl.Free;
      end;
    end;
      

  8.   

    另外,如果输出的结果需要排序,那么,在sl.CommaText := s;之后,for循环之前,调用一次
    sl.sort; 就可以了,算是附加功能了,呵呵
      

  9.   

    wxieyang老兄说的经过测试可以实现我的要求,但还有点小小的问题....如下
    我打开一个791K的文件后用wxieyang老兄的办法,运行的十分缓慢(约5分钟)有时候还会程序无反应.
    可以使程序加速的指令或其他的东东?
      

  10.   

    这么大的字符串啊,那你最好还是采用字符串扫描的方式来实现吧,因为采用我上面提到的方法,仅仅是个取巧的方式,处理处理小的字符串还不错,如果700多K,那还是扫描吧
    你可以先这样改下,看看速度如何:

        Memo2.Clear;
        Memo3.Clear;
        for I := 0 to sl.Count - 1 do
        begin
          if sl[I] <> '' then
          begin
            case sl[I][1] of
              'a': Memo2.Lines.Add(sl[I]);
              'b': Memo3.Lines.Add(sl[I]);
            end;
          end;
        end;
    改成
        memo2.Line.
        Memo2.Lines.BeginUpdate;
        try
          Memo3.Lines.BeginUpdate;
          try
            Memo2.Clear;
            Memo3.Clear;
            for I := 0 to sl.Count - 1 do
            begin
              if sl[I] <> '' then
              begin
                case sl[I][1] of
                  'a': Memo2.Lines.Add(sl[I]);
                  'b': Memo3.Lines.Add(sl[I]);
                end;
              end;
            end;
          finally
            Memo3.Lines.EndUpdate
          end;
        finally
          Memo2.Lines.EndUpdate
        end;如果这样修改之后,速度你能满意,那么就这么就行了,否则,只能进行字符串扫描的方式了
      

  11.   

    不好意思,上面的代码多了个
    memo2.Line. 
      

  12.   

    小弟新手...
    怎么改了以后点击无反应了?
     var
      sl: TStringList;
      s: AnsiString;
      I: Integer;
    begin
      sl := TStringList.Create;
        try 
          Memo3.Lines.BeginUpdate; 
          try 
            Memo2.Clear; 
            Memo3.Clear; 
            for I := 0 to sl.Count - 1 do 
            begin 
              if sl[I] <> '' then 
              begin 
                case sl[I][1] of 
                  'a': Memo2.Lines.Add(sl[I]);
                  'b': Memo3.Lines.Add(sl[I]); 
                end; 
              end; 
            end; 
          finally 
            Memo3.Lines.EndUpdate 
          end; 
        finally 
          Memo2.Lines.EndUpdate 
        end; end;
    end.
      

  13.   

    function GetNextToken(var p: PAnsiChar): AnsiString;
    var
      q: PAnsiChar;
    begin
      Result := '';
      if p^ = #0 then Exit;  q := p;
      Inc(p);
      while (p^ <> #0) and (p^ <> 'a') and (p^ <> 'b') do Inc(p);  if (p - 1)^ = #10 then
        Result := Copy(q, 1, Integer(p) - Integer(q) - 2) //过滤掉换行
      else
        Result := Copy(q, 1, Integer(p) - Integer(q))
    end;procedure TfrmMain.Button1Click(Sender: TObject);
    var
      Source: AnsiString;
      ps: PAnsiChar;
      Token: AnsiString;
    begin
      Source := Memo1.Lines.Text + #0; //加入一个结束标记
      if Source <> '' then
      begin
        ps := PAnsiChar(Source);   //转换成 PAnsiChar
        Token := GetNextToken(ps);
        Memo2.Lines.BeginUpdate;
        try
          Memo3.Lines.BeginUpdate;
          try
            repeat
              case Token[1] of
                'a': Memo2.Lines.Add(Token);
                'b': Memo3.Lines.Add(Token);
              end;
              Token := GetNextToken(ps);
            until Token = '';
          finally
            Memo3.Lines.EndUpdate;
          end;
        finally
          Memo2.Lines.EndUpdate;
        end;
      end;
    end;
    这是采用字符串扫描的方式实现的