使用[soWholeWord,soDown]
选项测试StrUtils.SearchBuf时,出现了一些意外结果。
program Project1;
Uses
SysUtils,StrUtils;
function WordFound(aString,searchString: String): Boolean;
begin
Result := SearchBuf(PChar(aString),Length(aString), 0, 0, searchString,
[soWholeWord,soDown]) <> nil;
end;
Procedure Test(aString,searchString: String);
begin
WriteLn('"',searchString,'" 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,searchString: String): Boolean;
begin
Result := SearchBuf(PChar(aString),Length(aString),Length(aString)-1,0,searchString,
[soWholeWord]) <> nil;
end;
Procedure TestRev(aString,searchString: String);
begin
WriteLn('"',searchString,'" in "',aString,'"',#9,' : ',
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的结果相同。
- 更新**
2条答案
按热度按时间hm2xizp91#
在我看来这是一个bug。下面是执行搜索的代码:
每次循环
while
时,我们都检查soWholeWord
是否在选项中,然后前进到下一个单词的开头,但我们只在以下情况下才这样做现在,
Result
是当前指向缓冲区的指针,也就是匹配的候选项,所以这个测试检查我们是否在被搜索字符串的开头。这个测试的意思是,如果搜索的字符串以非字母数字文本开始,我们就不能从非字母数字文本前进到第一个单词的开头。
现在,您可能决定删除以下测试
但是如果你这样做的话,你会发现如果这个单词正好位于字符串的开头,你就不再匹配它了,所以你会以另一种方式失败,正确的处理方法是确保如果我们位于字符串的开头,并且那里的文本是字母数字,
FindNextWordStart
不会前进。我猜原作者是这样写代码的:
然后他们发现字符串开头的单词不匹配,并将代码更改为:
没有人测试过如果字符串以非字母数字文本开头会发生什么。
这样的事情似乎可以完成工作:
lpwwtiir2#
修复版本:11 Alexandria 第2版:)
https://quality.embarcadero.com/browse/RSP-20731