OSDN Git Service

98fcc972b77f0fff61f20586dc5a7f6c589dca32
[gikonavigoeson/gikonavi.git] / MojuUtils.pas
1 unit MojuUtils;
2 //**************************
3 //      \8d¡\82Ì\8f\8a\81A\95\8e\9a\97ñ\92u\8a·\8aÖ\90\94 CustomStringReplace\81@\82¾\82¯\81B
4 //**************************
5
6 interface
7
8 uses
9         Windows, Classes, SysUtils;
10
11     function StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
12     function AnsiStrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
13     function ReplaceString(const S, OldPattern, NewPattern: string): string;
14
15     function CustomStringReplace(S , OldPattern: String;const  NewPattern: string): String; overload;
16     function CustomStringReplace(S , OldPattern: String;const  NewPattern: string; IgnoreCase : Boolean): String; overload;
17     procedure CustomStringReplace(var S : TStringList; OldPattern: String;const  NewPattern: string);overload;
18     procedure CustomStringReplace(var S : TStringList; OldPattern: String;const  NewPattern: string; IgnoreCase : Boolean);overload;
19
20
21 implementation
22
23 function CustomStringReplace(
24         S ,OldPattern: String;
25     const NewPattern: string
26 ): String;
27 {
28 var
29         position : Integer;
30     lenOld : Integer;//OldPattern\82Ì\92·\82³
31 }
32 begin
33     Result := ReplaceString(S,OldPattern,NewPattern);
34 {
35     position := 0;
36     lenOld := Length(OldPattern);
37     Result := '';
38     position := AnsiPos( OldPattern, S);
39     while  position  <> 0  do begin
40         Result := Result + Copy(S,1,position -1 ) + NewPattern;
41         Delete(S,1, position + lenOld - 1);
42         position := AnsiPos( OldPattern, S);
43     end;
44     if Length( S ) > 0 then begin
45         Result := Result + S;
46     end;
47 }
48
49 end;
50 function CustomStringReplace(
51         S , OldPattern: String;
52     const  NewPattern: string;
53     IgnoreCase : Boolean
54 ): String;
55 var
56         position : Integer;
57     lenOld : Integer;//OldPattern\82Ì\92·\82³
58     buffer : String;
59 begin
60     position := 0;
61     lenOld := Length(OldPattern);
62     Result := '';
63     if not IgnoreCase then begin
64         Result := ReplaceString(S,OldPattern,NewPattern);
65     end else begin
66         buffer := AnsiLowerCase(S);
67         OldPattern := AnsiLowerCase(OldPattern);
68         position := AnsiPos( OldPattern, buffer);
69         while  position  <> 0  do begin
70             Result := Result + Copy(S,1,position -1 ) + NewPattern;
71             Delete(S,1, position + lenOld - 1);
72             Delete(buffer,1, position + lenOld - 1);
73             position := AnsiPos( OldPattern, buffer);
74         end;
75         if Length( S ) > 0 then begin
76             Result := Result + S;
77         end;
78     end;
79 end;
80 procedure CustomStringReplace(
81         var S : TStringList;
82     OldPattern: String;
83     const  NewPattern: string;
84     IgnoreCase : Boolean
85 );
86 var
87     i : Integer;
88 begin
89     if not IgnoreCase then begin
90         for i := 0 to S.Count - 1 do begin
91                 S.Strings[i] := ReplaceString(S.Strings[i],OldPattern,NewPattern);
92         end;
93     end else begin
94         for i := 0 to S.Count - 1 do begin
95                 S.Strings[i] := CustomStringReplace( S.Strings[i], OldPattern, NewPattern,IgnoreCase );
96         end;
97     end;
98 end;
99 procedure CustomStringReplace(
100         var S : TStringList;
101     OldPattern: String;
102     const  NewPattern: string
103 );
104 var
105     i : Integer;
106 begin
107         for i := 0 to S.Count - 1 do begin
108         S.Strings[i] := ReplaceString(S.Strings[i],OldPattern,NewPattern);
109     end;
110 end;
111
112 function StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
113 asm
114         PUSH    EBX
115         PUSH    ESI
116         PUSH    EDI
117
118         MOV    ESI,ECX        { Point ESI to substr                  }
119         MOV    EDI,EAX        { Point EDI to s                        }
120
121         MOV    ECX,EDX        { ECX = search length                  }
122         SUB    ECX,EAX
123
124         MOV    EDX,SubstrEnd
125         SUB    EDX,ESI
126
127         DEC    EDX            { EDX = Length(substr) - 1              }
128         JS      @@fail        { < 0 ? return 0                        }
129         MOV    AL,[ESI]      { AL = first char of substr            }
130         INC    ESI            { Point ESI to 2'nd char of substr      }
131
132         SUB    ECX,EDX        { #positions in s to look at            }
133                               { = Length(s) - Length(substr) + 1      }
134         JLE    @@fail
135 @@loop:
136         REPNE  SCASB
137         JNE    @@fail
138         MOV    EBX,ECX        { save outer loop counter              }
139         PUSH    ESI            { save outer loop substr pointer        }
140         PUSH    EDI            { save outer loop s pointer            }
141
142         MOV    ECX,EDX
143         REPE    CMPSB
144         POP    EDI            { restore outer loop s pointer          }
145         POP    ESI            { restore outer loop substr pointer    }
146         JE      @@found
147         MOV    ECX,EBX        { restore outer loop counter            }
148         JMP    @@loop
149
150 @@fail:
151         XOR    EAX,EAX
152         JMP    @@exit
153
154 @@found:
155         MOV    EAX,EDI        { EDI points of char after match        }
156         DEC    EAX
157 @@exit:
158         POP    EDI
159         POP    ESI
160         POP    EBX
161 end;
162
163 function AnsiStrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd: PChar): PChar;
164 var
165   L2: Cardinal;
166   ByteType : TMbcsByteType;
167 begin
168   Result := nil;
169   if (StrStart = nil) or (StrStart^ = #0) or
170     (SubstrStart = nil) or (SubstrStart^ = #0) then Exit;
171   L2 := SubstrEnd - SubstrStart;
172   Result := StrPosEx(StrStart, StrEnd, SubstrStart, SubstrEnd);
173   while (Result <> nil) and (StrEnd - Result >= L2) do begin
174     ByteType := StrByteType(StrStart, Integer(Result-StrStart));
175     if (ByteType <> mbTrailByte) and
176       (CompareString(LOCALE_USER_DEFAULT, SORT_STRINGSORT, Result, L2, SubstrStart, L2) = 2)
177 then Exit;
178     if (ByteType = mbLeadByte) then Inc(Result);
179     Inc(Result);
180     Result := StrPosEx(Result, StrEnd, SubStrStart, SubStrEnd);
181   end;
182   Result := nil;
183 end;
184
185 function ReplaceString(const S, OldPattern, NewPattern: string): string;
186 var
187   ReplaceCount: Integer;
188   DestIndex: Integer;
189   i: Integer;
190   p, e, ps, pe: PChar;
191   Count: Integer;
192 begin
193   Result := S;
194   if OldPattern = '' then Exit;
195     p := PChar(S);
196     e := p + Length(S);
197     ps := PChar(OldPattern);
198     pe := ps + Length(OldPattern);
199     ReplaceCount := 0;
200     while p < e do begin
201       p := AnsiStrPosEx(p, e, ps, pe);
202       if p = nil then Break;
203       Inc(ReplaceCount);
204       Inc(p, Length(OldPattern));
205     end;
206     if ReplaceCount = 0 then Exit;
207     SetString(Result, nil, Length(S) +
208       (Length(NewPattern) - Length(OldPattern)) * ReplaceCount);
209     p := PChar(S);
210     DestIndex := 1;
211     for i := 0 to ReplaceCount - 1 do begin
212       Count := AnsiStrPosEx(p, e, ps, pe) - p;
213       Move(p^, Result[DestIndex], Count);
214       Inc(p, Count);//p := pp;
215       Inc(DestIndex, Count);
216       Move(NewPattern[1], Result[DestIndex], Length(NewPattern));
217       Inc(p, Length(OldPattern));
218       Inc(DestIndex, Length(NewPattern));
219     end;
220     Move(p^, Result[DestIndex], e - p);
221 end;
222
223 end.