乱码文件里查找指定字符串的大难题。求大神~

天下第一贱 2018-11-11 02:18:38

procedure TForm1.Button1Click(Sender: TObject);
var f: TextFile; s: string; sPos, ePos: Integer; sL: TStringList;
begin
sL := TStringList.Create;
AssignFile(f, 'a.log');
reset(f);
while not eof(f) do begin
Readln(f, s); // 赋值给S。
if Pos('TXN=', s) > 0 then begin // 找到指定字符串所在行
sPos := Pos('=', s); // 查找"="的位置
ePos := Pos(';', s); // 查找";"的位置
sL.Add(Copy(s, sPos + 1, ePos - sPos - 1)); // 含有";"就获取":"到";"的字符串
s1 := (sL.Text);
sL.Clear;
showmessage(s1);
end;
if Pos('TXP=', s) > 0 then begin // 找到指定字符串所在行
sPos := Pos('=', s); // 查找"="的位置
ePos := Pos(';', s); // 查找";"的位置
sL.Add(Copy(s, sPos + 1, ePos - sPos - 1)); // 含有";"就获取":"到";"的字符串
s2 := (sL.Text);
sL.Clear;
showmessage(s2);
end;
if Pos('"success":true,', s) > 0 then begin
showmessage('找到了');
end;
end;
FreeAndNil(sL);
closefile(f);
end;

用该按键事件对无乱码的文件查找是正常的,如果文件中包含有乱码就不正常了,求大神指点,附上带乱码文件。。
http://182.129.243.99:8000/aaa/a.log

...全文
77 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
wdonghai 2018-11-13
  • 打赏
  • 举报
回复

//Memo1:TMemo;
procedure TForm1.Button1Click(Sender: TObject);
var
MS:TMemoryStream;
p:PChar;
s:string;

procedure Find(ATxt:string);
var
iB,iE:Integer;
begin
iB:=Pos(ATxt,p);
while iB>0 do
begin
inc(p,iB+length(ATxt));
iE:=Pos(';',p);
Memo1.Lines.Add(ATxt);
Memo1.Lines.Add(Copy(p,1,iE-1));
iB:=Pos(ATxt,p);
end;
end;

begin
MS:=TMemoryStream.Create;
try
MS.LoadFromFile('a.log');
p:=PChar(MS.Memory);
Find('TXN=');
p:=PChar(MS.Memory);
Find('TXP=');
p:=PChar(MS.Memory);
s:='"success":true';
if Pos(s,p)>0 then
Memo1.Lines.Add('找到 '+s)
else Memo1.Lines.Add('没找到 '+s);
finally
MS.Free;
end;
end;
jobsju 2018-11-12
  • 打赏
  • 举报
回复
你的文件呢?传上来啊
chushouTV 2018-11-12
  • 打赏
  • 举报
回复
procedure TForm1.Button2Click(Sender: TObject); var SL : TStringList; i:string; begin SL := TStringList.Create; SL.LoadFromFile('a.log',TEncoding.UTF8); if SL.IndexOf('TXN=') > 0 then begin showmessage('ok'); end; SL.Free; end;
kenlewis 2018-11-12
  • 打赏
  • 举报
回复
提醒楼主,既然存在所谓的乱码,那么就有可能存在0x00,而在DELPHI里,按照字符串的方式处理,遇到这个会当成字符串的结尾,导致后面的内容不处理。所以,我建议楼主用二进制的方式查找替换。也很简单,将内容读取到一个流里,然后用CompareMem进行比较。
qtc26 2018-11-12
  • 打赏
  • 举报
回复
对于来源不明未知格式的文件可以试试用uedit32打开,然后再找规律。找到规律就简单了。
数据格式的文件只能用二进制来操作。
procedure readfile(filename:string);//数据文件,每条记录长235字节,包括帐户(uint),密码等信息。
const
ds:integer=235;//每条记录长235字节。
var
f:file;
numread,i:integer;
buf:array[0..234] of byte;
acc:uint;
accstr,mm,tmp:string;
begin
assignfile(f,filename);
reset(f,1);
blockread(f,buf,2,numread);//去掉文件头标识
blockread(f,buf,ds,numread);
while numread=235 do
begin
tmp:='';
mm:='';
for i:=0 to 7 do
begin
tmp:=tmp+inttohex(ord(buf[i]),2);
end;
acc:=strtoint64('$'+tmp);
accstr:=inttostr(acc);
for i:=8 to 27 do
begin
if buf[i]=0 then break;
mm:=mm+char(buf[i]);
end;
form1.memo1.Lines.Add(accstr+'----'+mm);
blockread(f,buf,ds,numread);
end;
closefile(f);
end;
BlueStorm 2018-11-12
  • 打赏
  • 举报
回复

//不会卡死,非常快 //只找到TXN的值,其他类推
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function FindPos(const StrBuf, FileBuf: TBytes; BeginNo: Integer=0): Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.FindPos(const StrBuf, FileBuf: TBytes; BeginNo: Integer): Integer;
var
  I: Integer;
begin
  Result := -1;
  for I := BeginNo to Length(FileBuf)-Length(StrBuf) do
  begin
    if CompareMem(@StrBuf[0], @FileBuf[I], Length(StrBuf)) then
    begin
      Result := I;
      Break;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Stream: TFileStream;
  Encoding: TEncoding;
  I, Pos1, Pos2, DataLen: Integer;
  StrBuf, FileBuf, RstBuf: TBytes;
begin
  Encoding := TEncoding.Ansi; //如果文件编码为Unicode,则改为TEncoding.Unicode

  Stream := TFileStream.Create('a.log', fmOpenRead);
  SetLength(FileBuf, Stream.Size);
  Stream.ReadBuffer(FileBuf, Stream.Size);
  Stream.Free;

  StrBuf := Encoding.GetBytes('TXN');
  Pos1 := FindPos(StrBuf, FileBuf);
  if Pos1 >= 0 then
  begin
    Pos1 := Pos1 + Length(StrBuf);
    StrBuf := Encoding.GetBytes('=');
    Pos1 := FindPos(StrBuf, FileBuf, Pos1);
    if Pos1 >= 0 then
    begin
      Pos2 := Pos1 + Length(StrBuf);;
      StrBuf := Encoding.GetBytes(';');
      Pos2 := FindPos(StrBuf, FileBuf, Pos2);
      if Pos2 >= 0 then
      begin
        if Encoding = TEncoding.Ansi then
        begin //Ansi
          DataLen := Pos2-Pos1-1;
          Pos1 := Pos1 + 1;
        end
        else
        begin //Unicode
          DataLen := Pos2-Pos1-2;
          Pos1 := Pos1 + 2;
        end;
        SetLength(RstBuf, DataLen);
        for I := 0 to DataLen-1 do
          RstBuf[I] := FileBuf[Pos1+I];
        ShowMessage('Found: ' + Trim(Encoding.GetString(RstBuf)));
      end;
    end;
  end;
end;

end.

天下第一贱 2018-11-11
  • 打赏
  • 举报
回复
楼上的大哥,试用了一下可以,但是我用于真正的LOG文件时就不行了,程序会卡死!!!?? 出现无响应。比如说我现在的LOG文件是1.5M的大小。上面我的a.log我已重新更新成原本的log文件了,我在你的基础上进行了修改你看看有没有不正确的地方。现在运行是不正常的。

procedure TForm1.Button1Click(Sender: TObject);
var
sL: TStringList;
sPos, ePos,i: Integer;
begin
  sL := TStringList.Create;
  sL.LoadFromFile('a.log');
  for i := 0 to sL.Count - 1 do begin
    if Pos('TXN=', sL[i]) > 0 then begin // 找到指定字符串所在行

      showmessage(sL[i]);
      sPos := Pos('=', sL[i]); // 查找"="的位置
      ePos := Pos(';', sL[i]); // 查找";"的位置
      sL.Add(Copy(sL[i], sPos + 1, ePos - sPos - 1)); // 含有";"就获取":"到";"的字符串
      s1 := sL.Text;
      sL.Clear;
      showmessage(s1);
    end;
  end;
 sL.Free;
end;
主要是为了找出TXN=后面的字符串并提取出来赋值给全局变量 S1..
jobsju 2018-11-11
  • 打赏
  • 举报
回复
procedure TForm1.Button2Click(Sender: TObject);
var
  SL : TStringList;
  i:Integer;
begin
  SL := TStringList.Create;
  SL.LoadFromFile('a.log');
  for i := 0 to SL.Count - 1 do
  begin
    if Pos('TXN=', SL[i]) <> 0 then
    showmessage('ok');
  end;
  SL.Free;
end;
天下第一贱 2018-11-11
  • 打赏
  • 举报
回复

procedure TForm1.Button2Click(Sender: TObject);
var
  SL : TStringList;
  i:string;
  begin
  SL := TStringList.Create;
  SL.LoadFromFile('a.log',TEncoding.UTF8);
  if SL.IndexOf('TXN=') > 0 then
  begin
 showmessage('ok');
  end;
  SL.Free;
end;
用这个办法也试过,更改编码UTF8,运行会报错,ANSI一样无反映。。。不知道应该用什么方法来读取这个文件了。。

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧