2014-09-16 15 views
6

StrUtils.SearchBuf seçeneğini [soWholeWord,soDown] seçeneği ile test ederken, bazı beklenmedik sonuçlar oluştu.SearchBuf soWholeWord beklenmedik çıktı

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. 

Neden ' Delphi' ve ' Delphi ' bir bütün kelime sayılmaz?

Tersine arama nedir?

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. 

Bundan hiç bir şey anlamıyorum. Bunun dışında fonksiyon buggy.

XE7, XE6 ve XE'de aynı sonuçlar.


Güncelleme

QC127635 StrUtils.SearchBuf fails with [soWholeWord] option

+1

QC örneğin belirtilen farklı hatalar vardır [Rapor #: 122357] (http://qc.embarcadero.com/wc/qcmain.aspx?d = 122357) – bummi

+1

@bummi, evet QC'yi aradım ve bu olay için hiçbir eşleşme bulamadım. –

cevap

4

Bana bir böcek gibi görünüyor. İşte arama yapar kod:

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 döngü yuvarlak Her zaman biz soWholeWord seçeneklerinde olup olmadığını kontrol ve ardından bir sonraki kelimenin başına ilerlemek. Ama biz sadece

Result <> @Buf[SelStart] 

Şimdi Result tampona kopyala işaretçi, bir maç için aday ilerletir eğer böyle yapar. Ve böylece bu test, aranan dizenin başında olup olmadığımızı kontrol eder.

Bu testin anlamı, aranan dize alfasayısal olmayan bir metinle başlıyorsa, alfasayısal olmayan metni ilk sözcüğün başlangıcına ilerletemeyeceğimiz anlamına gelir.

Şimdi,

Result <> @Buf[SelStart] 

için testi kaldırmak karar verebilir Ama yaparsan bunu doğru dizenin başında bulunuyorsa artık kelime maç olduğunu göreceksiniz söyledi. Yani sadece farklı bir şekilde başarısız olacaksın. Bununla başa çıkmanın en doğru yolu, dizenin başında olduğumuzda FindNextWordStart'un ilerlemesini sağlamak ve alfanümerik metin olduğundan emin olmaktır. onlar dize başında sözler maç olmaz keşfetti

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

ve kod değiştirildi:

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

Benim tahminim asıl yazar böyle bir kod yazdım olmasıdır

Ve hiç kimse, alfasayısal olmayan bir metinle başlayan dizgede ne olduğunu test etmedi.

böyle

şey işi gibi görünüyor:

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

'Ve dize alfasayısal olmayan bir metinle başlatılırsa ne olduğunu kimse test etmedi. İç çek, yıllar önce ve kimse bunu daha önce bulamadı. Test önemsizdir ve RTL'nin Emba tarafından birim tarafından test edilmiş olup olmadığını merak etmemizi sağlar. Teşekkürler, daha sonra bir QC dosyalayacağım. –

+2

Hmm. Beni başlatma! –

+0

@DavidHeffernan Orijinal kodu öneri kodunuzla değiştirdim ve hala çalışmıyor, söz konusu örnek aynı sonuçları veriyor. Delphi 10.1 veya 10.2. –