var i, Num :integer; for i:=0 to StringList.Count-1 do begin if StringList.Strings[i]=Str then Num := Num + 1; end;
function FindStrPos(mStr: stirng; mStrings: TStrings; var nX, nY: Integer): Boolean; var I, J: Integer; begin Result := False; for I := 0 to Pred(mStrings.Count) do begin J := Pos(mStr, mStrings[I]); if J > 0 then begin X := J; Y := I; Result := True; Break; end; end; end;
function FindStrPos(mStr: stirng; mStrings: TStrings; var nX, nY: Integer): Boolean; var I, J: Integer; begin Result := False; for I := 0 to Pred(mStrings.Count) do begin J := Pos(mStr, mStrings[I]); if J > 0 then begin nX := J; nY := I; Result := True; Break; end; end; end;
大不了逐个遍历String function FindStr(strFind: String; SourceStrings: TStrings; var nX, nY: Integer): Boolean; var iIndex: Integer; iYPos: Integer; begin Result := False; for iIndex := 0 to SourceStrings.Count then begin iYPos := Pos(strFind, SourceStrings[iIndex]); if iYPos > 0 then begin nX := iIndex; nY := iYPos; Result := True; Break; end; end; end;
首先要排序才能查找begin List.Sort; if List.Find('印刷厂许勤娟',index) then begin Label.Caption:=List.Strings[index]; end else INDEX:=h; Timer1.Enabled := False; showmessage('特等奖获得者'); Timer1.Enabled := true; end;
好像找不到返回-1吧
如果只是几个字符
用Pos('ABC',MyStringList.Text),
for i:=0 to StringList.Count-1 do
begin
if StringList.Strings[i]=Str then
Num := Num + 1;
end;
var
I, J: Integer;
begin
Result := False;
for I := 0 to Pred(mStrings.Count) do begin
J := Pos(mStr, mStrings[I]);
if J > 0 then begin
X := J;
Y := I;
Result := True;
Break;
end;
end;
end;
var
I, J: Integer;
begin
Result := False;
for I := 0 to Pred(mStrings.Count) do begin
J := Pos(mStr, mStrings[I]);
if J > 0 then begin
nX := J;
nY := I;
Result := True;
Break;
end;
end;
end;
function FindStr(strFind: String; SourceStrings: TStrings; var nX, nY: Integer): Boolean;
var
iIndex: Integer;
iYPos: Integer;
begin
Result := False;
for iIndex := 0 to SourceStrings.Count then begin
iYPos := Pos(strFind, SourceStrings[iIndex]);
if iYPos > 0 then begin
nX := iIndex;
nY := iYPos;
Result := True;
Break;
end;
end;
end;
List.Sort;
if List.Find('印刷厂许勤娟',index) then
begin
Label.Caption:=List.Strings[index];
end
else
INDEX:=h;
Timer1.Enabled := False;
showmessage('特等奖获得者');
Timer1.Enabled := true;
end;
标题头、标题尾如给定<title>,</title>,返回指定路径下所有找到的有标题
的文本文件;只给标题头,就当关键字处理,返回路径下所有含有此关键字的
文本文件。谁知竟不大好找,自己就花半天写了一个组件(单元名:LCSFileSch.pas),挺好用的。
我费力给你加上了帮助,可要给我加分呀!!你要想知道文本的行号的话(其实我觉得你在处理过程中用循环不必知道行号,反而减慢查询),在我的组件的函数中加入计数变量即可。我在程序中有意未使用 Pos函数,否则更简单。做好的文本查找器及代码,是我自己用的,所以你要的话Email儿我。
小龙 [email protected]
{*******************************************************}
{ }
{ LC's VCL Components }
{ }
{ Copyright (c) 2001,2004 Inprise Corporation }
{ }
{ 湖北 李超 }
{*******************************************************}unit LCSFileSch;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DBTables;type
TFoundFileEvent = procedure(Sender: TObject;FileName: string;FndStr: string
) of Object;
TFileFilter = set of (ftHtm,ftHtml,ftText,ftPas,ftAnyfile); //此集合属性待扩充
TLCSFileSch = class(TComponent)
private
FFindKey: string;
FFileName: string;
FSplittStr: string;
FFindEnd: string;
FPath: string;
FFileFilter: TFileFilter;
FOnFoundTitle: TFoundFileEvent;
FOnSearchFiles: TFoundFileEvent;
FOnFoundKey: TFoundFileEvent;
procedure SetFileName(const Value: string);
procedure SetFindKey(const Value: string);
procedure SetSplittStr(const Value: string);
procedure SetFindEnd(const Value: string);
procedure SetPath(const Value: string);
procedure SetFileFilter(const Value: TFileFilter); { Private declarations }
protected
{ Protected declarations } {在单个文件中查找}
procedure FindSimpleFile(AFileName: string;ADispName: string); {在指定路径下查找,无则当前路径,调用FindSimpleFile}
procedure FindInPath(APath: string); procedure DoFoundTitle(FileName: string; Title: string); dynamic;
procedure DoSearchFiles(FileName: string; FndStr: string); dynamic;
procedure DoFoundKey(FileName: string; Key: string); dynamic;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override; {执行查找}
procedure Execute;
published
{ Published declarations } {要查找的头个字符串,即标题头}
property FindKey: string read FFindKey write SetFindKey; {要查找的第二个字符串,即标题尾}
property FindEnd: string read FFindEnd write SetFindEnd; {若指定文件名,则只搜索这个文件}
property FileName: string read FFileName write SetFileName;
property SplittStr: string read FSplittStr write SetSplittStr; {***使用组件重点:用户使用组件时可在这三个事件中添加代码以实现获得找到
文件名及查找的字段名以及进行计数}
property OnSearchFiles: TFoundFileEvent read FOnSearchFiles write FOnSearchFiles;
property OnFoundKey: TFoundFileEvent read FOnFoundKey write FOnFoundKey;
property OnFoundTitle: TFoundFileEvent read FOnFoundTitle write FOnFoundTitle;
{指定路径,则搜索指定路径及子目录下全部文件}
property Path: string read FPath write SetPath;
property FileFilter: TFileFilter read FFileFilter write SetFileFilter
default [ftAnyfile];
end;{在一行(即字符串)中给定标题头、标题尾,若能找到标题返回真如找出HTML
<title> 和 </title>中的文章标题}
function _FindKeyInLine(Line: PChar;i: Integer;FindKey: PChar;j: Integer;
FindEnd: PChar;var Title: string): Boolean;{被_FindKeyInLine函数调用}
function _ReadTitle(Line: PChar;i: Integer;FindEnd: PChar): string;procedure Register;implementationprocedure Register;
begin
RegisterComponents('LC', [TLCSFileSch]);
end;{ TLCSFileSch }constructor TLCSFileSch.Create(AOwner: TComponent);
begin
inherited Create(AOwner); FFileFilter := [ftAnyfile];
FSplittStr := '-';
end;destructor TLCSFileSch.Destroy;
begin
inherited;end;procedure TLCSFileSch.DoSearchFiles(FileName, FndStr: string);
begin
if Assigned(FOnSearchFiles) then
FOnSearchFiles(self,FileName,FndStr);
end;procedure TLCSFileSch.DoFoundKey(FileName, Key: string);
begin
if Assigned(FOnFoundKey) then
FOnFoundKey(self,FileName,Key);end;procedure TLCSFileSch.DoFoundTitle(FileName, Title: string);
begin
if Assigned(FOnFoundTitle) then
FOnFoundTitle(self,FileName,Title);
end;procedure TLCSFileSch.Execute;
begin
FindInPath(FPath);
end;procedure TLCSFileSch.FindInPath(APath: string);
var
RetVal,l: Integer;
SearchPath,sPathTmp: string;
SearchRec,DSearchRec: TSearchRec;
FName,FileTmp: string; function IsDirNotation(ADirName: string): Boolean;
begin
Result := (ADirName = '.') or (ADirName = '..');
end;
begin
if (APath = '') or (APath = ' ') then
begin //空则搜索当前路径全部文件
SetLength(SearchPath,144);
if GetCurrentDirectory(144,PChar(SearchPath)) <> 0 then
begin
SetLength(SearchPath,StrLen(Pchar(SearchPath)));
end else begin
RaiseLastWin32Error;
Exit;
end;
end else begin
SearchPath := trim(APath);
end; if SearchPath[Length(SearchPath)] <> '\' then
SearchPath := SearchPath + '\';
if ((FFileName = '') or (FFileName = ' ')) then
begin
sPathTmp := SearchPath + '*.*'; RetVal := FindFirst(sPathTmp,faAnyfile,SearchRec);
try
while RetVal = 0 do
begin
FName := SearchRec.Name;
FileTmp := FName;
if not ((SearchRec.Attr and faArchive) > 0) then //只找非档案文件
begin
FName := ExtractFilePath(sPathTmp) + FName; l := Length(FName); //去掉不搜索的文件类型
SetLength(FName,l);
if not ((l > 3) and (FName[l-2] = 'O') and (FName[l-1]
= 'R') and (FName[l] = 'A') or (Pos('orant',FName) > 0)) then
FindSimpleFile(FName,FileTmp);
end; RetVal := FindNext(SearchRec);
end; //现在,在当前目录的子目录中进行查找
RetVal := FindFirst(sPathTmp,faDirectory,DSearchRec);
while RetVal = 0 do
begin
if ((DSearchRec.Attr and faDirectory) = faDirectory) and not
IsDirNotation(DSearchRec.Name) then
FindInPath(SearchPath + DSearchRec.Name); RetVal := FindNext(DSearchRec);
end;
finally
FindClose(SearchRec);
end; end else begin //指定文件名情况
if FileExists(SearchPath + FFileName) and (FFileName <> 'pagefile.sys')
then begin
FindSimpleFile(SearchPath + FFileName,FFileName);
end; end;end;procedure TLCSFileSch.FindSimpleFile(AFileName: string;ADispName: string);
var
F: TextFile;
PFindKey: PChar;
PLine: array[0..255] of char;
PFindEnd: PChar;
sTitle: string;
begin
//在名为FFileName的文件中搜索关键字字符串
if (AFileName = '') or (AFileName = ' ') or (FFindKey = '') or (FFindKey =
' ') then Exit;
if not FileExists(AFileName) then Exit; AssignFile(F,AFileName);
try
GetMem(PFindKey,Length(FFindKey) + 1);
StrPCopy(PFindKey,FFindKey);
try
GetMem(PFindEnd,Length(FFindEnd) + 1);
if not ((FFindEnd = '') or (FFindEnd = ' ')) then
StrPCopy(PFindEnd,FFindEnd);
try
Reset(F);
DoSearchFiles(AFileName,PFindKey); while not EOF(F) do //逐行读文件直到末尾
begin
Readln(F,PLine);
sTitle := '';
if _FindKeyInLine(PLine,0,PFindKey,0,PFindEnd,sTitle) then
begin
//HasFoundOneProc;
//ShowMessage('XXX!');
DoFoundKey(AFileName,PFindKey);
if sTitle <> '' then
begin
DoFoundTitle(AFileName,sTitle);
//ShowMessage(sTitle);
end;
end;
end;
finally
FreeMem(PFindEnd,Length(FFindEnd) + 1);
end;
finally
FreeMem(PFindKey,Length(FFindKey));
end;
finally
CloseFile(F);
end;
end;{procedure TLCSFileSch.HasFoundOneProc;
beginend;}procedure TLCSFileSch.SetFileFilter(const Value: TFileFilter);
begin
if Value <> FFileFilter then
FFileFilter := Value;
end;procedure TLCSFileSch.SetFileName(const Value: string);
begin
if Value <> FFileName then
FFileName := Value;
end;procedure TLCSFileSch.SetFindEnd(const Value: string);
begin
if Value <> FFindEnd then
FFindEnd := Value;
end;procedure TLCSFileSch.SetFindKey(const Value: string);
begin
if Value <> FFindKey then
FFindKey := Value;
end;procedure TLCSFileSch.SetPath(const Value: string);
begin
if Value <> FPath then
FPath := Value;
end;procedure TLCSFileSch.SetSplittStr(const Value: string);
begin
if Value <> FSplittStr then
FSplittStr := Value;
end;function _FindKeyInLine(Line: PChar;i: Integer;FindKey: PChar;j: Integer;FindEnd
:PChar;var Title:string): Boolean;
begin
Result := false;
if Length(FindKey) < 1 then Exit; if (Line[i] = #0) then Exit
else
if (FindKey[j] = #0) then
begin
Result := True;
Title := _ReadTitle(Line,i,FindEnd);
Exit;
end else begin
if Line[i] = FindKey[j] then
Result := Result or _FindKeyInLine(Line,i + 1,FindKey,j + 1,FindEnd,Title)
else
Result := Result or _FindKeyInLine(Line,i + 1,FindKey,0,FindEnd,Title);
end;end;function _ReadTitle(Line: PChar;i: Integer;FindEnd: PChar): string;
var
sTmp,sComp: string;
j,k: Integer;
begin
Result := '';
if FindEnd[0] = #0 then Exit;
j := i;
while not (Line[j + 1] = #0) do
begin
if j = i then
sTmp := Line[j]
else
sTmp := sTmp + Line[j]; sComp := ''; //sComp为当前字符串后的FinfEnd长度的字符串
for k := 0 to Length(FindEnd) - 1 do
begin
if k = 0 then sComp := Line[j + 1 + k]
else
sComp := sComp + Line[j + 1 + k];
end; if sComp = FindEnd then
begin
Result := sTmp;
break;
end; j := j + 1;
end;
end;end.
文件名快,因为其只读入了文件属性而未读入文件内容。注意,使用此组件或你自己开发时要在使用查找函数时用多线程处理,否则主界面和查找用一个线程再快的函数也会象死了样停在那里
没有测过,因为是Windows的直接支持,想来不会太慢)。闲话少说,主要是用了两个
消息 EM_FINDTEXT 和 EM_EXLINEFROMCHAR,前面一个可以查找一个特点的字符串(可以
指定是 CaseSentive或WholeWord 方式的组合,这个自己作还是很需要一点代码的,特别是
判断是否是一个Word,呵呵),这个消息的返回是查到的字符串的位置,但不是行号,要实现
到行号的转换,就是后面这个消息的功能了,具体你可以看一下帮助文件(在Win32SDK那个帮助
里面,不在Delphi那个默认的帮助里)。
另外TRichEdit里面也有一个FindText的Mothed,应该是一样的功能。(如果你追求速度,
可能直接用消息会快一些)。
消息的调用用PerForm(...),你应该会吧?