Cześć,
na wstępie zaznaczam, że przeszukałem forum, gotowce i google. Wydaje mi się, że problem nie jest skomplikowany i może nawet rozwiązany, jednak nie daję sobie z nim rady, ani z jego znalezieniem.
Potrzebuję dokonać StringReplace'a pod warunkiem, że część zastępowana nie jest częścią innego słowa. Wystąpień części zastępowanej może być wiele. Na przykład chcę zamienić wszystkie "kot" na "pies", ale pod warunkiem, że kot nie jest częścią innego słowa jak "kota","Szkot","aakotbbb" i tak:
"nie kot, nie sykot, ale kota bo to kot, kotowisko, kot" --> "nie pies, nie sykot, ale kota bo to pies, kotowisko, pies"
Moje starania:
tekst, zamienZ, zamienNA:String;
zamienZ:='kot';
zamienNA:='pies'
tekst:='nie kot, nie sykot, ale kota bo to kot, kotowisko, kot';
tekst:=StringReplace(tekst,' '+zamienZ+' ',' '+zamienNA+' ',[rfReplaceAll]);
tekst:=StringReplace(tekst,' '+zamienZ+',',' '+zamienNA+',',[rfReplaceAll]);
tekst:=StringReplace(tekst,' '+zamienZ+'.',' '+zamienNA+'.',[rfReplaceAll]);
tekst:=StringReplace(tekst,' '+zamienZ+';',' '+zamienNA+';',[rfReplaceAll]);
Ten sposób działa, ale ilość przypadków do sprawdzenia jest duża, a program wg. mnie robi dużo niepotrzebnej pracy. Poza tym nie podmieni wyrazu kot na początku i na końcu zmiennej tekst i to by było trzeba sprawdzać ręcznie, a nie mogę zrobić po prostu:
tekst:=StringReplace(tekst,zamienZ,zamienNA,[rfReplaceAll]);
Wystarczyłoby, żeby w StringReplace był warunek, że ma podmieniać tylko wtedy gdy przed i po miejscu podmiany nie występuje litera. Zbudowałem też coś takiego:
tekst, zamienZ, zamienNA:String;
zamienZ:='kot';
zamienNA:='pies'
tekst:='nie kot, nie sykot, ale kota bo to kot, kotowisko, kot';
gdzie:=Pos(zamienZ,tekst);
while (gdzie>0) and (not(scz(tekst[gdzie-1]))) and (not(scz(tekst[gdzie+Length(zamienZ)]))) do begin
tekst:=Copy(tekst,1,gdzie-1)+zamienNA+Copy(tekst,gdzie+Length(zamienZ),100000000);
gdzie:=Pos(zamienZ,tekst);
end;
gdzie scz jest funkcją sprawdzającą czy dany znak jest literą: a, b, c, ...:
result:=false;
if Pos('A',tekst)>0 then result:=true
else if Pos('a',tekst)>0 then result:=true
else if Pos('Ą',tekst)>0 then result:=true
[...]
Poza tym to nie działa też idealnie, bo jednak 'ą', 'ł' itd. to nie jeden a dwa znaki i warunki w pętli while się rozrastają, a program mi się wiesza.
Piszę w ObjectPascal w Lazarusie.