在Delphi 2009或更高版本(Unicode)中,是否有任何内置函数或小程序在某处编写,可以进行合理有效的全字搜索,其中提供定义单词的分隔符,例如:
function ContainsWord(Word, Str: string): boolean;
const { Delim holds the delimiters that are on either side of the word }
Delim = ' .;,:(){}"/\<>!?[]'#$91#$92#$93#$94'-+*='#$A0#$84;
其中:
Word: string; { is the Unicode string to search for }
Str: string; { is the Unicode string to be searched }
如果“Word”在字符串中,我只需要它返回true或false值。
某些地方必定有这样的东西,因为标准的查找对话框只有“仅匹配整个单词”作为其中一个选项。
这通常(或最佳)如何实施?
结论:
RRUZ的答案非常完美。 SearchBuf例程正是我所需要的。我甚至可以进入StrUtils例程,提取代码,并根据我的要求进行修改。
我很惊讶地发现SearchBuf不首先搜索该单词然后检查分隔符。相反,它一次查找字符串的字符,寻找分隔符。如果找到一个,则检查字符串和另一个分隔符。如果找不到,则查找另一个分隔符。为了效率,这非常聪明!
答案 0 :(得分:16)
您可以将SearchBuf功能与[soWholeWord]选项一起使用。
function SearchBuf(Buf: PAnsiChar; BufLen: Integer; SelStart: Integer; SelLength: Integer; SearchString: AnsiString; Options: TStringSearchOptions): PAnsiChar;
参见此示例
function ExistWordInString(aString:PWideChar;aSearchString:string;aSearchOptions: TStringSearchOptions): Boolean;
var
Size : Integer;
Begin
Size:=StrLen(aString);
Result := SearchBuf(aString, Size, 0, 0, aSearchString, aSearchOptions)<>nil;
End;
以这种方式使用
ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);
再见。
答案 1 :(得分:2)
仅仅因为Delphi的编辑器具有“单词匹配”功能,这并不意味着Delphi库提供它!
通常,在大多数语言中,这样做的方法是正则表达式。似乎他们(仍然)没有内置到Delphi中,因为有第三方库提供了这种功能。我发现的第一个例子是:http://delphi.about.com/od/toppicks/tp/delphi-regular-expressions.htm。
通常,您需要构建类似
的正则表达式myRegex = '[' + Delim + ']+' + Word + '[' + Delim + ']+';
if regexSearch (Str, myRegex) then ...
您需要从您获得的库的文档中获取详细信息。我的例子没有正确处理从Str的开头开始或者结尾的单词的情况,或者是str的全部。
答案 2 :(得分:0)
这个功能并不是你需要的,但它非常接近:
我希望它有用:
{ Copy all whole words from MainStr. The result will not have more than MaxChars characters. }
function CopyWords(MainStr: string; MaxChars: Integer): string;
VAR EndsInSpace: Boolean;
EndString, i: Integer;
NextChar: char;
begin
Assert(MaxChars > 0);
EndString:= MaxChars;
if Length(MainStr) > MaxChars then
begin
NextChar:= mainstr[MaxChars+1];
if (MainStr[MaxChars] <> ' ') AND (NextChar <> ' ')
then
begin
for i:= MaxChars downto 1 DO
if MainStr[i]= ' ' then
begin
EndString:= i;
Break;
end
end
else
if (MainStr[MaxChars] = ' ')
OR (MainStr[MaxChars] <> ' ') AND (NextChar = ' ')
then EndString:= MaxChars;
end;
Result:= CopyTo(MainStr, 1, EndString);
Result:= TrimRight(Result);
end;
答案 3 :(得分:0)
如果您具有以下功能
function ExistWordInString(aString:PWideChar;aSearchString:string;aSearchOptions: TStringSearchOptions): Boolean;
var
Size : Integer;
Begin
Size:=StrLen(aString);
Result := SearchBuf(aString, Size, 0, 0, aSearchString, aSearchOptions)<>nil;
End;
并将其称为:
ExistWordInString('Go Delphi Go','Delphi',[soWholeWord,soDown]);
如果你打电话一次,你可能不会遇到任何问题。但是如果你在循环中调用它(例如1000次或更多次),首先使用Pos函数(如下所示)会令人惊讶地给你额外的性能
function ExistWordInString(const AString:string;const ASearchString:string;ASearchOptions: TStringSearchOptions): Boolean;
var
Size : Integer;
AWChar: PWideChar;
begin
if Pos(LowerCase(ASearchString), LowerCase(AString)) = 0 then
begin
Exit(False);
end;
AWChar := PWideChar(AString);
Size:=StrLen(AWChar);
Result := SearchBuf(AWChar, Size, 0, 0, ASearchString, ASearchOptions)<>nil;
end;