Create a replace function for strings in Delphi
Editor's note: In fact, Delphi's StringReplace function is specifically designed to meet this need. But we also publish this article - at least the author provides an alternative, and the spirit of exploration should be encouraged! This is my first article here, and since my level is not very high, I will discuss a basic but very practical issue. I hope it can give you some help. Friends who have used VB or ASP know that there is a very practical replace function in VB. Its function is to replace the string that matches the substring (also called the pattern string) in a string with a specified string. For example, there is such a string: s:='apple is apple!'. After using the replace function to replace (s,'apple','box'), s becomes 'box is box!'. The length of the string also changes accordingly. This is a very useful function. Everyone knows that structured query statements sql are often used when developing database systems, and this statement is sensitive to some characters, such as single quotes. If a single quote appears in the sql statement quotes (because single quotes are used in sq l) program will cause unexpected errors, and can even be used by others to cause serious security vulnerabilities in the system (this is the famous SQL injection attack, I believe everyone still remembers what was discovered by the CSDN forum before) This is a loophole). At this time, you need to replace the single quotes with other strings or empty strings during database operations, and then replace them back when reading the data, so that the single quotes can be recorded in the data record without errors. However, I didn't find a similar function in Delphi (maybe I didn't find it?), which was really inconvenient, so I wrote one myself, which will be much more convenient in future database system development. After talking so much nonsense, here is the code, it should be easier to understand with comments.
PRocedure replace(var s:string;const SourceChar:pchar;const RChar:pchar); // The first parameter is the original string, the second is the pattern string, and the third is the replacement string var ta,i,j:integer ; m,n,pn,sn:integer; SLen,SCLen,RCLen:integer;//SLen represents the length of the original string, SCLen represents the length passed by the mode, RCLen represents the length of the replacement string IsSame:integer; newp:array of char;// Used to save the replaced character array begin SLen:=strlen(pchar(s));SCLen:=strlen(SourceChar);RCLen:=strlen(RChar); j:=pos(string(SourceChar),s); s:=s+chr(0);ta:=0;i:=j; while s[i]<>chr(0) do // This loop uses ta counts the number of times the pattern string appears in the original string begin n:=0;IsSame:=1; for m:=i to i+SCLen-1 do begin if m>SLen then begin IsSame:=0;break; end; if s[m]<>sourceChar[n] then begin IsSame:=0;break; end; n:=n+1; end; if IsSame=1 then begin ta:=ta+1;i:=m; end else i:=i+1; end; if j>0 then begin pn:=0;sn:=1; setlength(newp,SLen-ta*SCLen+ta*RCLen+1);// Allocate the length of newp, +1 means there is a #0 terminator behind it
while s[sn]<>chr(0) do // Mainly Loop, start replacing begin n:=0;IsSame:=1; for m:=sn to sn+SCLen-1 do // Compare whether the substring is the same as the pattern string begin if m>SLen then begin IsSame:=0;break; end; if s[m]<>sourceChar[n] then begin IsSame:=0;break; end; n:=n+1; end; if IsSame=1 then// Same begin for m:=0 to RCLen-1 do begin newp[pn]:=RChar[m];pn:=pn+1; end; sn:=sn+SCLen; end else begin // Different newp[pn]:=s[sn]; pn:=pn+1;sn:=sn+1; end; end; newp[pn]:=#0; s:=string(newp); / / resets , replacement completed! end; end; In fact, this is a basic data structure issue. Today, when we often program with drag-and-drop controls, we should just practice data structure. Of course, this function is not optimally written. I tested replacing a 10,000-word string and it took half a second. The time complexity is still relatively high. If you have a better way, please discuss it!