我当前项目的一部分是将搜索结果(仅限文件名)与搜索字符串(多个单词)进行比较。目前我有一个非常基本的机制来识别结果的相关性,所有这些都由一个函数处理。
搜索开始时,我将搜索字符串拆分为关键字字符串列表...
procedure TSearcherThread.ParseKeywords;
var
S, T: String;
P: Integer;
begin
//Clear current list of keywords
FKeywords.Clear;
S:= LowerCase(Trim(FSearchString));
//Remove all excess spaces
while Pos(' ', S) > 1 do
S:= StringReplace(S, ' ', ' ', [rfReplaceAll]);
if Copy(S, Length(S)-1, 1) <> ';' then
S:= S + ';';
//Parse out keywords
while Length(S) > 0 do begin
P:= Pos(';', S);
T:= Copy(S, 1, P-1);
Delete(S, 1, P);
FKeywords.Append(T);
end;
end;
现在,当我遍历要搜索的文件的主列表时,我将每个文件名传递给这个函数......
function TSearcherThread.MatchKeywords(const Filename: String): Single;
var
S: String; //Temp keywords
FN: String; //Filename
X: Integer; //Iterator
C: Integer; //Match counter
begin
Result:= 0; //Default no match
S:= Trim(LowerCase(FSearchString)); //Lowercase Keywords, trim outside spaces
FN:= LowerCase(ExtractFileName(Filename)); //Get lowercase filename
Delete(FN, Pos('.', FN), MAXINT); //Strip off extension leaving only the name
//Check if exact match
if FN = S then Result:= 2;
//If nothing matches yet, then look for individual keywords...
if Result < 2 then begin
C:= 0;
if FKeywords.Count > 0 then begin
//Iterate through keywords
for X := 0 to FKeywords.Count - 1 do begin
//If keyword is found in filename
if Pos(FKeywords[X], FN) > 0 then begin
Inc(C);
end;
end;
//Return how often keywords showed up
Result:= C / FKeywords.Count;
end;
end;
end;
它的工作原理是函数传回相关的十进制数。结果 0 表示不匹配,介于 0 和 1 之间表示部分匹配,数字越大表示匹配越好,1 表示找到所有关键字,2 表示完全匹配。我还可以进行比较以仅包含具有一定百分比的结果,如下所示:
M:= MatchKeywords(Filename);
if M >= 0.2 then AddResult(Filename);
问题是我上面的方法只考虑了AND操作,这意味着它需要所有的关键字,并比较找到了多少关键字。但是,我还想同时实现AND和OR操作的组合,这是我的结构不支持的。所以我需要重新编写这个函数的核心来使这成为可能。
我想知道的不是如何写这个,而是德尔福中有什么东西可以让这成为可能吗?有人向我提到TDictionary
哈希表是我需要的,但我不知道它与我正在做的事情有什么关系,因为我从未使用过它们。如果模式匹配已经存在于 Delphi XE2 中,我只是不想重新发明模式匹配的轮子。