加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – SearchBuf soWholeWord意外输出

发布时间:2020-12-15 09:52:12 所属栏目:大数据 来源:网络整理
导读:使用[soWholeWord,soDown]选项测试 StrUtils.SearchBuf时,会发生一些意外结果. program Project1;Uses SysUtils,StrUtils;function WordFound(aString,searchString: String): Boolean;begin Result := SearchBuf(PChar(aString),Length(aString),searchStri
使用[soWholeWord,soDown]选项测试 StrUtils.SearchBuf时,会发生一些意外结果.

program Project1;

Uses
  SysUtils,StrUtils;

function WordFound(aString,searchString: String): Boolean;
begin
  Result := SearchBuf(PChar(aString),Length(aString),searchString,[soWholeWord,soDown]) <> nil;
end;

Procedure Test(aString,searchString: String);
begin
  WriteLn('"','" in "',aString,'"',#9,' : ',WordFound(aString,searchString));
end;

begin
  Test('Delphi','Delphi');   // True
  Test('Delphi ','Delphi');  // True
  Test(' Delphi','Delphi');  // False
  Test(' Delphi ','Delphi'); // False
  ReadLn;
end.

为什么’Delphi’和’Delphi’不被认为是一个完整的词?

反向搜索怎么样?

function WordFoundRev(aString,Length(aString)-1,[soWholeWord]) <> nil;
end;

Procedure TestRev(aString,WordFoundRev(aString,searchString));
end;

begin
  TestRev('Delphi','Delphi');   // False
  TestRev('Delphi ','Delphi');  // True
  TestRev(' Delphi','Delphi');  // False
  TestRev(' Delphi ','Delphi'); // True
  ReadLn;
end.

我根本没有任何意义.除了功能有缺陷.

XE7,XE6和XE中的结果相同.

更新

QC127635 StrUtils.SearchBuf fails with [soWholeWord] option

解决方法

对我来说这看起来像个错误.这是搜索的代码:

while SearchCount > 0 do
begin
  if (soWholeWord in Options) and (Result <> @Buf[SelStart]) then
    if not FindNextWordStart(Result) then Break;
  I := 0;
  while (CharMap[(Result[I])] = (SearchString[I+1])) do
  begin
    Inc(I);
    if I >= Length(SearchString) then
    begin
      if (not (soWholeWord in Options)) or
         (SearchCount = 0) or
         ((Byte(Result[I])) in WordDelimiters) then
        Exit;
      Break;
    end;
  end;
  Inc(Result,Direction);
  Dec(SearchCount);
end;

每次循环while循环时,我们检查soWholeWord是否在选项中,然后前进到下一个单词的开头.但是我们只会这样做

Result <> @Buf[SelStart]

现在,Result是当前指针进入缓冲区,匹配的候选者.因此,此测试检查我们是否处于搜索字符串的开头.

此测试的含义是,如果搜索的字符串以非字母数字文本开头,则我们无法超越非字母数字文本到第一个单词的开头.

现在,您可能决定删除测试

Result <> @Buf[SelStart]

但是,如果你这样做,你会发现如果它位于字符串的开头,你就不再匹配该单词.所以你只会以不同的方式失败.解决这个问题的正确方法是确保如果我们位于字符串的开头,则FindNextWordStart不会前进,并且文本中包含字母数字.

我的猜测是原作者编写了这样的代码:

if (soWholeWord in Options) then
  if not FindNextWordStart(Result) then Break;

然后他们发现字符串开头的单词不匹配,并将代码更改为:

if (soWholeWord in Options) and (Result <> @Buf[SelStart]) then
  if not FindNextWordStart(Result) then Break;

如果字符串以非字母数字文本开头,则没有人测试发生了什么.

这样的事情似乎完成了工作:

if (soWholeWord in Options) then
  if (Result <> @Buf[SelStart]) or not Result^.IsLetterOrDigit then
    if not FindNextWordStart(Result) then Break;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读