OSDN Git Service

大文字小文字区別なし置換も高速化した
authorh677 <h677>
Wed, 26 Nov 2003 03:57:24 +0000 (03:57 +0000)
committerh677 <h677>
Wed, 26 Nov 2003 03:57:24 +0000 (03:57 +0000)
MojuUtils.pas

index 98fcc97..fb0d1bd 100644 (file)
@@ -1,7 +1,15 @@
 unit MojuUtils;
-//**************************
+//******************************************************************************
 //     \8d¡\82Ì\8f\8a\81A\95\8e\9a\97ñ\92u\8a·\8aÖ\90\94 CustomStringReplace\81@\82¾\82¯\81B
-//**************************
+//  \8eg\82¢\95û\82Í\81A
+//\81@CustomStringReplace(
+//\81@   \8c³\82Ì\95\8e\9a\97ñ\81iString\82à\82µ\82­\82ÍTStringList),
+//\81@   \8c\9f\8dõ\95\8e\9a\97ñ\81iString),
+//             \92u\8a·\95\8e\9a\97ñ\81iString),
+//      \91å\95\8e\9a\8f¬\95\8e\9a\81iBoolean)True:\8bæ\95Ê\82µ\82È\82¢\81@false or \8fÈ\97ª:\8bæ\95Ê\82·\82é
+//
+// Delphi-ML\82Ì\8bL\8e\9669334\82É\8dÚ\82Á\82Ä\82¢\82½\83R\81[\83h\82ð\8aÛ\83p\83N\83\8a\82µ\82Ü\82µ\82½\81B
+//******************************************************************************
 
 interface
 
@@ -11,6 +19,7 @@ uses
     function StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
     function AnsiStrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
     function ReplaceString(const S, OldPattern, NewPattern: string): string;
+    function IgnoCaseReplaceString(const S, OldPattern, NewPattern: string): string;
 
     function CustomStringReplace(S , OldPattern: String;const  NewPattern: string): String; overload;
     function CustomStringReplace(S , OldPattern: String;const  NewPattern: string; IgnoreCase : Boolean): String; overload;
@@ -20,95 +29,6 @@ uses
 
 implementation
 
-function CustomStringReplace(
-       S ,OldPattern: String;
-    const NewPattern: string
-): String;
-{
-var
-       position : Integer;
-    lenOld : Integer;//OldPattern\82Ì\92·\82³
-}
-begin
-    Result := ReplaceString(S,OldPattern,NewPattern);
-{
-    position := 0;
-    lenOld := Length(OldPattern);
-    Result := '';
-    position := AnsiPos( OldPattern, S);
-    while  position  <> 0  do begin
-        Result := Result + Copy(S,1,position -1 ) + NewPattern;
-        Delete(S,1, position + lenOld - 1);
-        position := AnsiPos( OldPattern, S);
-    end;
-    if Length( S ) > 0 then begin
-        Result := Result + S;
-    end;
-}
-
-end;
-function CustomStringReplace(
-       S , OldPattern: String;
-    const  NewPattern: string;
-    IgnoreCase : Boolean
-): String;
-var
-       position : Integer;
-    lenOld : Integer;//OldPattern\82Ì\92·\82³
-    buffer : String;
-begin
-    position := 0;
-    lenOld := Length(OldPattern);
-    Result := '';
-    if not IgnoreCase then begin
-        Result := ReplaceString(S,OldPattern,NewPattern);
-    end else begin
-        buffer := AnsiLowerCase(S);
-        OldPattern := AnsiLowerCase(OldPattern);
-        position := AnsiPos( OldPattern, buffer);
-        while  position  <> 0  do begin
-            Result := Result + Copy(S,1,position -1 ) + NewPattern;
-            Delete(S,1, position + lenOld - 1);
-            Delete(buffer,1, position + lenOld - 1);
-            position := AnsiPos( OldPattern, buffer);
-        end;
-        if Length( S ) > 0 then begin
-            Result := Result + S;
-        end;
-    end;
-end;
-procedure CustomStringReplace(
-       var S : TStringList;
-    OldPattern: String;
-    const  NewPattern: string;
-    IgnoreCase : Boolean
-);
-var
-    i : Integer;
-begin
-    if not IgnoreCase then begin
-        for i := 0 to S.Count - 1 do begin
-               S.Strings[i] := ReplaceString(S.Strings[i],OldPattern,NewPattern);
-        end;
-    end else begin
-        for i := 0 to S.Count - 1 do begin
-               S.Strings[i] := CustomStringReplace( S.Strings[i], OldPattern, NewPattern,IgnoreCase );
-        end;
-    end;
-end;
-procedure CustomStringReplace(
-       var S : TStringList;
-    OldPattern: String;
-    const  NewPattern: string
-);
-var
-    i : Integer;
-begin
-       for i := 0 to S.Count - 1 do begin
-       S.Strings[i] := ReplaceString(S.Strings[i],OldPattern,NewPattern);
-    end;
-end;
-
 function StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
 asm
         PUSH    EBX
@@ -162,62 +82,179 @@ end;
 
 function AnsiStrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
 var
-  L2: Cardinal;
-  ByteType : TMbcsByteType;
+    L2: Cardinal;
+    ByteType : TMbcsByteType;
 begin
-  Result := nil;
-  if (StrStart = nil) or (StrStart^ = #0) or
-    (SubstrStart = nil) or (SubstrStart^ = #0) then Exit;
-  L2 := SubstrEnd - SubstrStart;
-  Result := StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd);
-  while (Result <> nil) and (StrEnd - Result >= L2) do begin
-    ByteType := StrByteType(StrStart, Integer(Result-StrStart));
-    if (ByteType <> mbTrailByte) and
-      (CompareString(LOCALE_USER_DEFAULT, SORT_STRINGSORT, Result, L2, SubstrStart, L2) = 2)
-then Exit;
-    if (ByteType = mbLeadByte) then Inc(Result);
-    Inc(Result);
-    Result := StrPosEx(Result, StrEnd, SubStrStart, SubStrEnd);
-  end;
-  Result := nil;
+    Result := nil;
+    if (StrStart = nil) or (StrStart^ = #0) or
+       (SubstrStart = nil) or (SubstrStart^ = #0) then Exit;
+
+    L2 := SubstrEnd - SubstrStart;
+    Result := StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd);
+
+    while (Result <> nil) and (StrEnd - Result >= L2) do begin
+       ByteType := StrByteType(StrStart, Integer(Result-StrStart));
+       if (ByteType <> mbTrailByte) and
+               (CompareString(LOCALE_USER_DEFAULT, SORT_STRINGSORT, Result, L2, SubstrStart, L2) = 2)
+       then Exit;
+       if (ByteType = mbLeadByte) then Inc(Result);
+       Inc(Result);
+       Result := StrPosEx(Result, StrEnd, SubStrStart, SubStrEnd);
+    end;
+    Result := nil;
 end;
 
 function ReplaceString(const S, OldPattern, NewPattern: string): string;
 var
-  ReplaceCount: Integer;
-  DestIndex: Integer;
-  i: Integer;
-  p, e, ps, pe: PChar;
-  Count: Integer;
+    ReplaceCount: Integer;
+    DestIndex: Integer;
+    i: Integer;
+    p, e, ps, pe: PChar;
+    Count: Integer;
 begin
-  Result := S;
-  if OldPattern = '' then Exit;
+    Result := S;
+    if OldPattern = '' then Exit;
     p := PChar(S);
     e := p + Length(S);
     ps := PChar(OldPattern);
     pe := ps + Length(OldPattern);
     ReplaceCount := 0;
     while p < e do begin
-      p := AnsiStrPosEx(p, e, ps, pe);
-      if p = nil then Break;
-      Inc(ReplaceCount);
-      Inc(p, Length(OldPattern));
+        p := AnsiStrPosEx(p, e, ps, pe);
+        if p = nil then Break;
+        Inc(ReplaceCount);
+        Inc(p, Length(OldPattern));
     end;
     if ReplaceCount = 0 then Exit;
     SetString(Result, nil, Length(S) +
-      (Length(NewPattern) - Length(OldPattern)) * ReplaceCount);
+    (Length(NewPattern) - Length(OldPattern)) * ReplaceCount);
     p := PChar(S);
     DestIndex := 1;
     for i := 0 to ReplaceCount - 1 do begin
-      Count := AnsiStrPosEx(p, e, ps, pe) - p;
-      Move(p^, Result[DestIndex], Count);
-      Inc(p, Count);//p := pp;
-      Inc(DestIndex, Count);
-      Move(NewPattern[1], Result[DestIndex], Length(NewPattern));
-      Inc(p, Length(OldPattern));
-      Inc(DestIndex, Length(NewPattern));
+        Count := AnsiStrPosEx(p, e, ps, pe) - p;
+        Move(p^, Result[DestIndex], Count);
+        Inc(p, Count);//p := pp;
+        Inc(DestIndex, Count);
+        Move(NewPattern[1], Result[DestIndex], Length(NewPattern));
+        Inc(p, Length(OldPattern));
+        Inc(DestIndex, Length(NewPattern));
+    end;
+    Move(p^, Result[DestIndex], e - p);
+end;
+
+function IgnoCaseReplaceString(const S, OldPattern, NewPattern: string): string;
+var
+    ReplaceCount: Integer;
+    DestIndex: Integer;
+    i: Integer;
+    p, e{, ps, pe}: PChar;
+    p2, e2, ps2, pe2: PChar;
+    Count: Integer;
+    bufferS : String;
+    bufferOldPattern : String;
+begin
+    Result := S;
+    bufferS := AnsiLowerCase(S);
+    bufferOldPattern := AnsiLowerCase(OldPattern);
+
+    if OldPattern = '' then Exit;
+    p  := PChar(S);
+    p2 := PChar(bufferS);
+    e  := p + Length(S);
+    e2 := p2 + Length(bufferS);
+    //ps       := PChar(OldPattern);
+    ps2        := PChar(bufferOldPattern);
+    //pe       := ps + Length(OldPattern);
+    pe2        := ps2 + Length(bufferOldPattern);
+
+    ReplaceCount := 0;
+    while p2 < e2 do begin
+        p2 := AnsiStrPosEx(p2, e2, ps2, pe2);
+        if p2 = nil then Break;
+        Inc(ReplaceCount);
+        Inc(p2, Length(bufferOldPattern));
+    end;
+    if ReplaceCount = 0 then Exit;
+    SetString(Result, nil, Length(bufferS) +
+    (Length(NewPattern) - Length(bufferOldPattern)) * ReplaceCount);
+    p2 := PChar(bufferS);
+    DestIndex := 1;
+    for i := 0 to ReplaceCount - 1 do begin
+        Count := AnsiStrPosEx(p2, e2, ps2, pe2) - p2;
+        Move(p^, Result[DestIndex], Count);
+        Inc(p, Count);//p := pp;
+        Inc(p2, Count);//p := pp;
+        Inc(DestIndex, Count);
+        Move(NewPattern[1], Result[DestIndex], Length(NewPattern));
+        Inc(p, Length(OldPattern));
+        Inc(p2, Length(OldPattern));
+        Inc(DestIndex, Length(NewPattern));
     end;
     Move(p^, Result[DestIndex], e - p);
 end;
 
+function CustomStringReplace(
+       S ,OldPattern: String;
+    const NewPattern: string
+): String;
+
+begin
+    Result := ReplaceString(S,OldPattern,NewPattern);
+end;
+
+
+function CustomStringReplace(
+       S , OldPattern: String;
+    const  NewPattern: string;
+    IgnoreCase : Boolean
+): String;
+begin
+    Result := '';
+    if not IgnoreCase then begin
+        Result := ReplaceString(S,OldPattern,NewPattern);
+    end else begin
+        Result := IgnoCaseReplaceString(S,OldPattern,NewPattern);
+    end;
+end;
+
+
+procedure CustomStringReplace(
+       var S : TStringList;
+    OldPattern: String;
+    const  NewPattern: string;
+    IgnoreCase : Boolean
+);
+var
+    i : Integer;
+begin
+    S.BeginUpdate;
+    if not IgnoreCase then begin
+        for i := 0 to S.Count - 1 do begin
+            S.Strings[i] := ReplaceString(S.Strings[i], OldPattern,NewPattern);
+        end;
+    end else begin
+        for i := 0 to S.Count - 1 do begin
+            S.Strings[i] := IgnoCaseReplaceString(S.Strings[i], OldPattern,NewPattern);
+        end;
+    end;
+    S.EndUpdate;
+end;
+
+
+procedure CustomStringReplace(
+       var S : TStringList;
+    OldPattern: String;
+    const  NewPattern: string
+);
+var
+    i : Integer;
+begin
+    S.BeginUpdate;
+       for i := 0 to S.Count - 1 do begin
+               S.Strings[i] := ReplaceString(S.Strings[i], OldPattern,NewPattern);;
+    end;
+    S.EndUpdate;
+end;
+
+
 end.