Janilabo

Janilabo | StrMultiReplace[2]

Sep 12th, 2012
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 7.99 KB | None | 0 0
  1. type
  2.   TReplaceFlag = (rfReplaceAll, rfIgnoreCase);
  3.   TReplaceFlags = set of TReplaceFlag;
  4.   TMatchMethod = (mmAll, mmBackward, mmIgnoreCase, mmOverlap, mmWholeWords, mmStrictWW);
  5.   TMatchMethods = set of TMatchMethod;
  6.   TMultiReplace = record
  7.     oldStr, newStr: string;  
  8.     offset: Integer;
  9.     replaceFlags: TReplaceFlags;
  10.   end;
  11.   TMultiReplaceArray = array of TMultiReplace;
  12.   TMultiReplace2 = record
  13.     oldStr, newStr: string;      
  14.     offset: Integer;
  15.     matchMethods: TMatchMethods;
  16.   end;
  17.   TMultiReplaceArray2 = array of TMultiReplace2;
  18.  
  19. function MultiReplace(oldStr, newStr: string; offset: Integer; replaceFlags: TReplaceFlags): TMultiReplace;
  20. begin
  21.   Result.oldStr := oldStr;
  22.   Result.newStr := newStr;
  23.   Result.offset := offset;
  24.   Result.replaceFlags := replaceFlags;
  25. end;
  26.  
  27. function MultiReplace2(oldStr, newStr: string; offset: Integer; matchMethods: TMatchMethods): TMultiReplace2;
  28. begin
  29.   Result.oldStr := oldStr;
  30.   Result.newStr := newStr;
  31.   Result.offset := offset;
  32.   Result.matchMethods := matchMethods;
  33. end;
  34.  
  35. function StrMultiReplace(Text: string; MRA: TMultiReplaceArray): string;
  36. var
  37.   h, i, x, tL, f: Integer;
  38.   rgx_fs, tmp: string;
  39.   m: TStrArray;
  40.   r: TRegexMatchArray;
  41. begin  
  42.   h := High(MRA);
  43.   tL := Length(Text);
  44.   if ((h < 0) or (tL < 1)) then
  45.     Exit;
  46.   for i := 0 to h do
  47.     if ((MRA[i].oldStr <> '') and (tL > MRA[i].offset) and (tL >= Length(MRA[i].oldStr)))  then
  48.     begin                          
  49.       Result := Copy(Text, MRA[i].offset, ((tL - MRA[i].offset) + 1));
  50.       if (MRA[i].offset < 1) then
  51.         MRA[i].offset := 1;  
  52.       rgx_fs := '/' + PregQuote(MRA[i].oldStr) + '/';
  53.       if (rfIgnoreCase in MRA[i].replaceFlags) then
  54.         rgx_fs := (rgx_fs + 'i');
  55.       rgx_fs := (rgx_fs + 'm');
  56.       case (rfReplaceAll in MRA[i].replaceFlags) of
  57.         True:
  58.         begin
  59.           tmp := Result;  
  60.           f := 0;
  61.           SetLength(m, Round(tL div Length(MRA[i].oldStr)));
  62.           while PregMatchEx(rgx_fs, tmp, r) do
  63.           begin              
  64.             tmp := Replace(tmp, r[0].MatchedText, '');
  65.             m[f] := r[0].MatchedText;                    
  66.             SetLength(r, 0);
  67.             Inc(f);
  68.           end;                    
  69.           if (f > 0) then
  70.             for x := 0 to (f - 1) do
  71.               Result := Replace(Result, m[x], MRA[i].newStr);
  72.           SetLength(m, 0);
  73.         end;
  74.         False:
  75.         if PregMatchEx(rgx_fs, Result, r) then
  76.         begin
  77.           Result := (Copy(Result, 1, (r[0].Offset - 1)) + MRA[i].newStr + Copy(Result, (r[0].Offset + r[0].Length), (Length(Result) - (r[0].Offset + r[0].Length) + 1)));
  78.           SetLength(r, 0);
  79.         end;
  80.       end;                                    
  81.       Result := (Copy(Text, 1, (MRA[i].offset - 1)) + Result);
  82.       Text := Result;
  83.     end;
  84. end;
  85.  
  86. function StrMultiReplace2(Text: string; MRA2: TMultiReplaceArray2): string;
  87. var
  88.   fsL, tL, h, i, c, e, t, x: Integer;
  89.   rgx_fs, tmp: string;
  90.   r: TRegexMatchArray;
  91.   p: TIntArray;
  92. begin
  93.   Result := Text;
  94.   h := High(MRA2);
  95.   if ((h < 0) or (Text = '')) then
  96.     Exit;
  97.   for i := 0 to h do
  98.   begin
  99.     tL := Length(Text);
  100.     fsL := Length(MRA2[i].oldStr);
  101.     if ((tL < 1) or (Length(MRA2[i].oldStr) > tL) or (MRA2[i].oldStr = '')) then
  102.       Exit;
  103.     if (MRA2[i].offset < 1) then
  104.       MRA2[i].offset := 1;  
  105.     MRA2[i].oldStr := PregQuote(MRA2[i].oldStr);  
  106.     if (mmWholeWords in MRA2[i].matchMethods) then
  107.     begin
  108.       if (mmStrictWW in MRA2[i].matchMethods) then  
  109.         rgx_fs := '/(?<!\S)' + MRA2[i].oldStr + '(?!\S)/'
  110.       else
  111.         rgx_fs := '/(^|\b|(?<=\s))' + MRA2[i].oldStr + '((?=\s)|\b|$)/'
  112.     end else
  113.       rgx_fs := '/' + MRA2[i].oldStr + '/';
  114.     if (mmIgnoreCase in MRA2[i].matchMethods) then
  115.       rgx_fs := (rgx_fs + 'i');
  116.     rgx_fs := (rgx_fs + 'm');  
  117.     case (mmBackward in MRA2[i].matchMethods) of
  118.       True:
  119.       begin      
  120.         Result := Copy(Text, 1, MRA2[i].offset);    
  121.         tmp := Result;    
  122.         SetLength(p, Length(tmp));
  123.         while PregMatchEx(rgx_fs, tmp, r) do
  124.         begin
  125.           p[c] := (r[0].Offset + c);
  126.           Inc(c);
  127.           Delete(tmp, r[0].Offset, 1);
  128.           SetLength(r, 0);
  129.         end;        
  130.         SetLength(p, c);
  131.         TIAUnique(p);
  132.         c := Length(p);
  133.         InvertTIA(p);
  134.         if (c > 0) then
  135.           if not (mmAll in MRA2[i].matchMethods) then
  136.           begin
  137.             Delete(Result, p[0], fsL);
  138.             Insert(MRA2[i].newStr, Result, p[0]);
  139.           end else
  140.           case (not (mmWholeWords in MRA2[i].matchMethods) and (mmOverlap in MRA2[i].matchMethods)) of
  141.             True:
  142.             for x := 0 to (c - 1) do
  143.             begin      
  144.               e := fsL;
  145.               if (x > 0) then
  146.                 if ((p[(x - 1)] - p[x]) <= fsL) then
  147.                   e := (p[(x - 1)] - p[x]);
  148.               Delete(Result, p[x], e);
  149.               Insert(MRA2[i].newStr, Result, p[x]);
  150.             end;
  151.             False:  
  152.             begin  
  153.               e := 0;
  154.               if (mmWholeWords in MRA2[i].matchMethods) then
  155.                 e := 1;
  156.               for x := 0 to (c - 1) do
  157.               begin                                        
  158.                 Inc(t);
  159.                 if (x > 0) then
  160.                   if ((p[(x - t)] - p[x]) < (fsL - e)) then
  161.                     Continue;
  162.                 Delete(Result, p[x], fsL);
  163.                 Insert(MRA2[i].newStr, Result, p[x]);
  164.                 t := 0;
  165.               end;
  166.             end;
  167.           end;
  168.         Result := (Result + Copy(Text, (MRA2[i].offset + 1), (Length(Text) - MRA2[i].offset)));
  169.       end;  
  170.       False:
  171.       begin
  172.         Result := Copy(Text, MRA2[i].offset, ((tL - MRA2[i].offset) + 1));
  173.         case (mmAll in MRA2[i].matchMethods) of
  174.           True:
  175.           begin
  176.             if (not (mmWholeWords in MRA2[i].matchMethods) and (mmOverlap in MRA2[i].matchMethods)) then
  177.             begin
  178.               tmp := Result;
  179.               SetLength(p, Length(tmp));
  180.               while PregMatchEx(rgx_fs, tmp, r) do
  181.               begin
  182.                 p[c] := (r[0].Offset + c);
  183.                 Inc(c);
  184.                 Delete(tmp, r[0].Offset, 1);
  185.                 SetLength(r, 0);
  186.               end;        
  187.               SetLength(p, c);
  188.               TIAUnique(p);
  189.               c := Length(p);
  190.               for x := (c - 1) downto 0 do
  191.               begin          
  192.                 e := fsL;
  193.                 if (x < (c - 1)) then
  194.                   if ((p[(x + 1)] - p[x]) <= fsL) then
  195.                     e := (p[(x + 1)] - p[x]);        
  196.                 Delete(Result, p[x], e);
  197.                 Insert(MRA2[i].newStr, Result, p[x]);
  198.               end;
  199.             end else
  200.               Result := PregReplace(rgx_fs, MRA2[i].newStr, Result);  
  201.           end;
  202.           False:
  203.           if PregMatchEx(rgx_fs, Result, r) then
  204.           begin
  205.             Result := (Copy(Result, 1, (r[0].Offset - 1)) + MRA2[i].newStr + Copy(Result, (r[0].Offset + r[0].Length), (Length(Result) - (r[0].Offset + r[0].Length) + 1)));
  206.             SetLength(r, 0);  
  207.           end;
  208.         end;                                                              
  209.         Result := (Copy(Text, 1, (MRA2[i].offset - 1)) + Result);    
  210.       end;
  211.     end;  
  212.     SetLength(p, 0);
  213.     tmp := '';
  214.     Text := Result;
  215.   end;  
  216. end;
  217.  
  218. var
  219.   TEXT, TEXT2: String;
  220.   MRA: TMultiReplaceArray;
  221.   MRA2: TMultiReplaceArray2;
  222.  
  223. begin
  224.   ClearDebug;
  225.   TEXT := 'Janilabo was here.. Right? Well, janilabo is a NEWBIE for REAL.';
  226.   MRA := [MultiReplace('Janilabo', 'Newbie', 1, [rfReplaceAll, rfIgnoreCase]), MultiReplace('Newbie', 'Master', 1, [rfReplaceAll])];
  227.   TEXT2 := StrMultiReplace(TEXT, MRA);
  228.   WriteLn(TEXT2);
  229.   SetLength(MRA, 0);
  230.   MRA2 := [MultiReplace2('Janilabo', 'Newbie', 1, [mmAll, mmIgnoreCase]), MultiReplace2('Newbie', 'Master', 1, [mmAll])];
  231.   TEXT2 := StrMultiReplace2(TEXT, MRA2);
  232.   WriteLn(TEXT2);
  233.   SetLength(MRA2, 0);
  234. end.
Advertisement
Add Comment
Please, Sign In to add comment