Janilabo

Janilabo | Find()

Aug 29th, 2012
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.71 KB | None | 0 0
  1. const
  2.   TEXT = 'TestesTESTTestest test TEST Test Test.';
  3.   FIND_STR = 'test';
  4.  
  5. type
  6.   TMatchMethod = (mmAll, mmBackward, mmIgnoreCase, mmOverlap, mmWholeWords, mmStrictWW);
  7.   TMatchMethods = set of TMatchMethod;
  8.  
  9. function Find(Text, FindStr: string; Methods: TMatchMethods; Offset: Integer): TIntArray;
  10. var
  11.   tL, fsL, d, i, t: Integer;
  12.   rgx_fs: string;            
  13.   r: TRegexMatchArray;
  14. begin
  15.   fsL := Length(FindStr);
  16.   tL := Length(Text);
  17.   if ((tL < 1) or (Length(FindStr) > tL) or (FindStr = '')) then
  18.     Exit;            
  19.   if (Offset < 1) then
  20.     Offset := 1;    
  21.   FindStr := PregQuote(FindStr);  
  22.   if (mmWholeWords in Methods) then
  23.   begin
  24.     if (mmStrictWW in Methods) then  
  25.       rgx_fs := '/(?<!\S)' + FindStr + '(?!\S)/'
  26.     else
  27.       rgx_fs := '/(^|\b|(?<=\s))' + FindStr + '((?=\s)|\b|$)/';
  28.   end else
  29.     rgx_fs := '/' + FindStr + '/';
  30.   if (mmIgnoreCase in Methods) then
  31.     rgx_fs := (rgx_fs + 'i');
  32.   rgx_fs := (rgx_fs + 'm');
  33.   if (mmOverlap in Methods) then
  34.     SetLength(Result, (tL - (fsL - 1)))
  35.   else
  36.     SetLength(Result, ((tL div fsL) + 1));        
  37.   case (mmBackward in Methods) of
  38.     True:
  39.     begin
  40.       Text := Copy(Text, 1, Offset);
  41.       while PregMatchEx(rgx_fs, Text, r) do
  42.       begin
  43.         Result[d] := (r[0].Offset + d);
  44.         Inc(d);
  45.         Delete(Text, r[0].Offset, 1);
  46.         SetLength(r, 0);
  47.       end;        
  48.       SetLength(Result, d);    
  49.       if (mmAll in Methods) then  
  50.         InvertTIA(Result)              
  51.       else
  52.         if (d > 0) then                        
  53.           Result := [Result[(d - 1)]];
  54.       if (mmAll in Methods) then
  55.         if not (mmOverlap in Methods) then
  56.           if (d > 1) then
  57.             for i := (0 + t) to ((d - 2) - t) do
  58.               if ((Result[i] - Result[(i + 1)]) <= fsL) then
  59.               begin      
  60.                 Result[(i + 1)] := Result[i];
  61.                 Delete(Result, i, 1);
  62.                 Inc(t);
  63.               end;  
  64.     end;
  65.     False:                    
  66.     begin    
  67.       if (Offset > 1) then
  68.         Delete(Text, 1, (Offset - 1));
  69.       if (mmAll in Methods) then
  70.       begin    
  71.         while PregMatchEx(rgx_fs, Text, r) do
  72.         begin
  73.           Result[d] := ((r[0].Offset + d) + (Offset - 1));
  74.           Inc(d);
  75.           Delete(Text, r[0].Offset, 1);
  76.           SetLength(r, 0);
  77.         end;
  78.         SetLength(Result, d);
  79.         if (mmAll in Methods) then
  80.           if not (mmOverlap in Methods) then
  81.             if (d > 1) then
  82.               for i := (0 + t) to ((d - 2) - t) do
  83.                 if ((Result[(i + 1)] - Result[i]) <= fsL) then
  84.                 begin        
  85.                   Result[(i + 1)] := Result[i];
  86.                   Delete(Result, i, 1);
  87.                   Inc(t);
  88.                 end;
  89.       end else
  90.       if PregMatchEx(rgx_fs, Text, r) then
  91.       begin
  92.         Result := [((r[0].Offset + d) + (Offset - 1))];
  93.         SetLength(r, 0);
  94.       end;
  95.     end;
  96.   end;
  97.   TIAUnique(Result);      
  98. end;
  99.  
  100. var
  101.   l, h, i, i2, s, o: Integer;
  102.   TIA: TIntArray;
  103.   m_sets: array of TMatchMethods;
  104.   TSA: TStrArray;
  105.                
  106. procedure BuildSets(find_method: (fmBackward, fmForward));
  107. begin
  108.   case find_method of
  109.     fmForward:
  110.     begin
  111.       TSA := ['[]', '[mmIgnoreCase]', '[mmIgnoreCase, mmAll]', '[mmIgnoreCase, mmAll, mmOverlap]', '[mmIgnoreCase, mmAll, mmOverlap, mmWholeWords]', '[mmIgnoreCase, mmAll, mmOverlap, mmWholeWords, mmStrictWW]'];
  112.       l := Length(FIND_STR);
  113.       o := 1;  
  114.       s := High(TSA);
  115.       SetLength(m_sets, (s + 1));
  116.       m_sets[0] := [];
  117.       m_sets[1] := [mmIgnoreCase];
  118.       m_sets[2] := [mmIgnoreCase, mmAll];
  119.       m_sets[3] := [mmIgnoreCase, mmAll, mmOverlap];
  120.       m_sets[4] := [mmIgnoreCase, mmAll, mmOverlap, mmWholeWords];
  121.       m_sets[5] := [mmIgnoreCase, mmAll, mmOverlap, mmWholeWords, mmStrictWW];  
  122.     end;
  123.     fmBackward:
  124.     begin
  125.       TSA := ['[mmBackward]', '[mmBackward, mmIgnoreCase]', '[mmBackward, mmIgnoreCase, mmAll]', '[mmBackward, mmIgnoreCase, mmAll, mmOverlap]', '[mmBackward, mmIgnoreCase, mmAll, mmOverlap, mmWholeWords]', '[mmBackward, mmIgnoreCase, mmAll, mmOverlap, mmWholeWords, mmStrictWW]'];
  126.       l := Length(FIND_STR);
  127.       o := Length(TEXT);
  128.       s := High(TSA);
  129.       SetLength(m_sets, (s + 1));
  130.       m_sets[0] := [mmBackward];
  131.       m_sets[1] := [mmBackward, mmIgnoreCase];
  132.       m_sets[2] := [mmBackward, mmIgnoreCase, mmAll];
  133.       m_sets[3] := [mmBackward, mmIgnoreCase, mmAll, mmOverlap];
  134.       m_sets[4] := [mmBackward, mmIgnoreCase, mmAll, mmOverlap, mmWholeWords];
  135.       m_sets[5] := [mmBackward, mmIgnoreCase, mmAll, mmOverlap, mmWholeWords, mmStrictWW];  
  136.     end;    
  137.   end;
  138. end;
  139.  
  140. begin                
  141.   ClearDebug;                              
  142.   BuildSets(fmForward);      
  143.   WriteLn('FORWARD:');
  144.   for i := 0 to s do
  145.   begin
  146.     TIA := Find(TEXT, FIND_STR, m_sets[i], o);
  147.     h := High(TIA);  
  148.     WriteLn('Find(''' + FIND_STR + ''', ''' + TEXT + ''', ' + TSA[i] + ', ' + IntToStr(o) + ')')
  149.     for i2 := 0 to h do
  150.       WriteLn('Match[' + IntToStr(i2 + 1) + ']: ' + Copy(TEXT, TIA[i2], l) + ' (@POS.' + IntToStr(TIA[i2]) + ')');
  151.     WriteLn('');
  152.     SetLength(TIA, 0);
  153.   end;                
  154.   BuildSets(fmBackward)
  155.   WriteLn('BACKWARD:');
  156.   for i := 0 to s do
  157.   begin
  158.     TIA := Find(TEXT, FIND_STR, m_sets[i], o);
  159.     h := High(TIA);  
  160.     WriteLn('Find(''' + FIND_STR + ''', ''' + TEXT + ''', ' + TSA[i] + ', ' + IntToStr(o) + ')')
  161.     for i2 := 0 to h do
  162.       WriteLn('Match[' + IntToStr(i2 + 1) + ']: ' + Copy(TEXT, TIA[i2], l) + ' (@POS.' + IntToStr(TIA[i2]) + ')');
  163.     if (i < s) then
  164.       WriteLn('');
  165.     SetLength(TIA, 0);
  166.   end;
  167.   SetLength(m_sets, 0);
  168.   SetLength(TSA, 0);      
  169. end.
Advertisement
Add Comment
Please, Sign In to add comment