strutils.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. {$mode objfpc}
  2. {$h+}
  3. {
  4. $Id$
  5. This file is part of the Free Pascal run time library.
  6. Copyright (c) 1999-2000 by the Free Pascal development team
  7. Delphi/Kylix compatibility unit: String handling routines.
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. unit strutils;
  15. interface
  16. uses
  17. SysUtils{, Types};
  18. { ---------------------------------------------------------------------
  19. Case sensitive search/replace
  20. ---------------------------------------------------------------------}
  21. Function AnsiResemblesText(const AText, AOther: string): Boolean;
  22. Function AnsiContainsText(const AText, ASubText: string): Boolean;
  23. Function AnsiStartsText(const ASubText, AText: string): Boolean;
  24. Function AnsiEndsText(const ASubText, AText: string): Boolean;
  25. Function AnsiReplaceText(const AText, AFromText, AToText: string): string;
  26. Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
  27. Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
  28. { ---------------------------------------------------------------------
  29. Case insensitive search/replace
  30. ---------------------------------------------------------------------}
  31. Function AnsiContainsStr(const AText, ASubText: string): Boolean;
  32. Function AnsiStartsStr(const ASubText, AText: string): Boolean;
  33. Function AnsiEndsStr(const ASubText, AText: string): Boolean;
  34. Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;
  35. Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
  36. Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
  37. { ---------------------------------------------------------------------
  38. Playthingies
  39. ---------------------------------------------------------------------}
  40. Function DupeString(const AText: string; ACount: Integer): string;
  41. Function ReverseString(const AText: string): string;
  42. Function AnsiReverseString(const AText: AnsiString): AnsiString;
  43. Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
  44. Function RandomFrom(const AValues: array of string): string; overload;
  45. Function IfThen(AValue: Boolean; const ATrue: string; AFalse: string): string;
  46. Function IfThen(AValue: Boolean; const ATrue: string): string; // ; AFalse: string = ''
  47. { ---------------------------------------------------------------------
  48. VB emulations.
  49. ---------------------------------------------------------------------}
  50. Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  51. Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  52. Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  53. Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  54. Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;
  55. Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  56. Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  57. Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  58. {$ifndef ver1_0}
  59. Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  60. Function LeftStr(const AText: WideString; const ACount: Integer): WideString;
  61. Function RightStr(const AText: WideString; const ACount: Integer): WideString;
  62. Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
  63. {$endif}
  64. { ---------------------------------------------------------------------
  65. Extended search and replace
  66. ---------------------------------------------------------------------}
  67. const
  68. { Default word delimiters are any character except the core alphanumerics. }
  69. WordDelimiters: set of Char = [#0..#255] - ['a'..'z','A'..'Z','1'..'9','0'];
  70. type
  71. TStringSeachOption = (soDown, soMatchCase, soWholeWord);
  72. TStringSearchOptions = set of TStringSeachOption;
  73. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String; Options: TStringSearchOptions): PChar;
  74. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String): PChar; // ; Options: TStringSearchOptions = [soDown]
  75. Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
  76. Function PosEx(const SubStr, S: string): Integer; // Offset: Cardinal = 1
  77. Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
  78. { ---------------------------------------------------------------------
  79. Soundex Functions.
  80. ---------------------------------------------------------------------}
  81. type
  82. TSoundexLength = 1..MaxInt;
  83. Function Soundex(const AText: string; ALength: TSoundexLength): string;
  84. Function Soundex(const AText: string): string; // ; ALength: TSoundexLength = 4
  85. type
  86. TSoundexIntLength = 1..8;
  87. Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
  88. Function SoundexInt(const AText: string): Integer; //; ALength: TSoundexIntLength = 4
  89. Function DecodeSoundexInt(AValue: Integer): string;
  90. Function SoundexWord(const AText: string): Word;
  91. Function DecodeSoundexWord(AValue: Word): string;
  92. Function SoundexSimilar(const AText, AOther: string; ALength: TSoundexLength): Boolean;
  93. Function SoundexSimilar(const AText, AOther: string): Boolean; //; ALength: TSoundexLength = 4
  94. Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;
  95. Function SoundexCompare(const AText, AOther: string): Integer; //; ALength: TSoundexLength = 4
  96. Function SoundexProc(const AText, AOther: string): Boolean;
  97. type
  98. TCompareTextProc = Function(const AText, AOther: string): Boolean;
  99. Const
  100. AnsiResemblesProc: TCompareTextProc = @SoundexProc;
  101. implementation
  102. { ---------------------------------------------------------------------
  103. Auxiliary functions
  104. ---------------------------------------------------------------------}
  105. Procedure NotYetImplemented (FN : String);
  106. begin
  107. Raise Exception.CreateFmt('Function "%s" (strutils) is not yet implemented',[FN]);
  108. end;
  109. { ---------------------------------------------------------------------
  110. Case sensitive search/replace
  111. ---------------------------------------------------------------------}
  112. Function AnsiResemblesText(const AText, AOther: string): Boolean;
  113. begin
  114. NotYetImplemented(' AnsiResemblesText');
  115. end;
  116. Function AnsiContainsText(const AText, ASubText: string): Boolean;
  117. begin
  118. NotYetImplemented(' AnsiContainsText');
  119. end;
  120. Function AnsiStartsText(const ASubText, AText: string): Boolean;
  121. begin
  122. NotYetImplemented(' AnsiStartsText');
  123. end;
  124. Function AnsiEndsText(const ASubText, AText: string): Boolean;
  125. begin
  126. NotYetImplemented(' AnsiEndsText');
  127. end;
  128. Function AnsiReplaceText(const AText, AFromText, AToText: string): string;
  129. begin
  130. NotYetImplemented(' AnsiReplaceText');
  131. end;
  132. Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
  133. begin
  134. NotYetImplemented(' AnsiMatchText');
  135. end;
  136. Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
  137. begin
  138. NotYetImplemented(' AnsiIndexText');
  139. end;
  140. { ---------------------------------------------------------------------
  141. Case insensitive search/replace
  142. ---------------------------------------------------------------------}
  143. Function AnsiContainsStr(const AText, ASubText: string): Boolean;
  144. begin
  145. NotYetImplemented(' AnsiContainsStr');
  146. end;
  147. Function AnsiStartsStr(const ASubText, AText: string): Boolean;
  148. begin
  149. NotYetImplemented(' AnsiStartsStr');
  150. end;
  151. Function AnsiEndsStr(const ASubText, AText: string): Boolean;
  152. begin
  153. NotYetImplemented(' AnsiEndsStr');
  154. end;
  155. Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;
  156. begin
  157. NotYetImplemented(' AnsiReplaceStr');
  158. end;
  159. Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
  160. begin
  161. NotYetImplemented(' AnsiMatchStr');
  162. end;
  163. Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
  164. begin
  165. NotYetImplemented(' AnsiIndexStr');
  166. end;
  167. { ---------------------------------------------------------------------
  168. Playthingies
  169. ---------------------------------------------------------------------}
  170. Function DupeString(const AText: string; ACount: Integer): string;
  171. var i,l : integer;
  172. begin
  173. result:='';
  174. if aCount>=0 then
  175. begin
  176. l:=length(atext);
  177. SetLength(result,aCount*l);
  178. for i:=0 to ACount-1 do
  179. move(atext[1],Result[l*i+1],l);
  180. end;
  181. end;
  182. Function ReverseString(const AText: string): string;
  183. var c: char;
  184. i,j:longint;
  185. begin
  186. setlength(result,length(atext));
  187. i:=1; j:=length(atext);
  188. while (i<=j) do
  189. begin
  190. result[i]:=atext[j-i+1];
  191. inc(i);
  192. end;
  193. end;
  194. Function AnsiReverseString(const AText: AnsiString): AnsiString;
  195. begin
  196. NotYetImplemented(' AnsiReverseString');
  197. end;
  198. Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
  199. begin
  200. NotYetImplemented(' StuffString');
  201. end;
  202. Function RandomFrom(const AValues: array of string): string; overload;
  203. begin
  204. NotYetImplemented(' RandomFrom');
  205. end;
  206. Function IfThen(AValue: Boolean; const ATrue: string; AFalse: string): string;
  207. begin
  208. if avalue then result:=atrue else result:=afalse;
  209. end;
  210. Function IfThen(AValue: Boolean; const ATrue: string): string; // ; AFalse: string = ''
  211. begin
  212. if avalue then result:=atrue else result:='';
  213. end;
  214. { ---------------------------------------------------------------------
  215. VB emulations.
  216. ---------------------------------------------------------------------}
  217. Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  218. begin
  219. Result:=Copy(AText,1,ACount);
  220. end;
  221. Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  222. var j,l:integer;
  223. begin
  224. l:=length(atext);
  225. j:=ACount;
  226. if j>l then j:=l;
  227. Result:=Copy(AText,l-j+1,j);
  228. end;
  229. Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  230. begin
  231. if (ACount=0) or (AStart>length(atext)) then
  232. exit('');
  233. Result:=Copy(AText,AStart,ACount);
  234. end;
  235. Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  236. begin
  237. NotYetImplemented(' LeftBStr');
  238. end;
  239. Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  240. begin
  241. NotYetImplemented(' RightBStr');
  242. end;
  243. Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;
  244. begin
  245. NotYetImplemented(' MidBStr');
  246. end;
  247. Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  248. begin
  249. NotYetImplemented(' AnsiLeftStr');
  250. end;
  251. Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  252. begin
  253. NotYetImplemented(' AnsiRightStr');
  254. end;
  255. Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  256. begin
  257. NotYetImplemented(' AnsiMidStr');
  258. end;
  259. {$ifndef ver1_0}
  260. Function LeftStr(const AText: WideString; const ACount: Integer): WideString;
  261. begin
  262. NotYetImplemented(' LeftStr');
  263. end;
  264. Function RightStr(const AText: WideString; const ACount: Integer): WideString;
  265. begin
  266. NotYetImplemented(' RightStr');
  267. end;
  268. Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
  269. begin
  270. NotYetImplemented(' MidStr');
  271. end;
  272. {$endif}
  273. { ---------------------------------------------------------------------
  274. Extended search and replace
  275. ---------------------------------------------------------------------}
  276. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String; Options: TStringSearchOptions): PChar;
  277. begin
  278. NotYetImplemented(' SearchBuf');
  279. end;
  280. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String): PChar; // ; Options: TStringSearchOptions = [soDown]
  281. begin
  282. NotYetImplemented(' SearchBuf');
  283. end;
  284. Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
  285. var i : pchar;
  286. begin
  287. if (offset<1) or (offset>length(s)) then exit(0);
  288. i:=strpos(@s[1],@substr[offset]);
  289. if i=nil then
  290. PosEx:=0
  291. else
  292. PosEx:=(i-pchar(s))+offset;
  293. end;
  294. Function PosEx(const SubStr, S: string): Integer; // Offset: Cardinal = 1
  295. begin
  296. posex:=posex(substr,s,1);
  297. end;
  298. Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
  299. var l : longint;
  300. begin
  301. if (offset<1) or (offset>length(s)) then exit(0);
  302. l:=length(s);
  303. while (offset<=l) and (s[offset]<>c) do inc(offset);
  304. if offset>l then
  305. posex:=0
  306. else
  307. posex:=offset;
  308. end;
  309. { ---------------------------------------------------------------------
  310. Soundex Functions.
  311. ---------------------------------------------------------------------}
  312. Const
  313. SScore : array[1..255] of Char =
  314. ('0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 1..32
  315. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 33..64
  316. '0','1','2','3','0','1','2','i','0','2','2','4','5','5','0','1','2','6','2','3','0','1','i','2','i','2', // 64..90
  317. '0','0','0','0','0','0', // 91..95
  318. '0','1','2','3','0','1','2','i','0','2','2','4','5','5','0','1','2','6','2','3','0','1','i','2','i','2', // 96..122
  319. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 123..154
  320. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 155..186
  321. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 187..218
  322. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 219..250
  323. '0','0','0','0','0'); // 251..255
  324. Function Soundex(const AText: string; ALength: TSoundexLength): string;
  325. Var
  326. S,PS : Char;
  327. I,L : integer;
  328. begin
  329. Result:='';
  330. PS:=#0;
  331. If Length(AText)>0 then
  332. begin
  333. Result:=Upcase(AText[1]);
  334. I:=2;
  335. L:=Length(AText);
  336. While (I<=L) and (Length(Result)<ALength) do
  337. begin
  338. S:=SScore[Ord(AText[i])];
  339. If Not (S in ['0','i',PS]) then
  340. Result:=Result+S;
  341. If (S<>'i') then
  342. PS:=S;
  343. Inc(I);
  344. end;
  345. end;
  346. L:=Length(Result);
  347. If (L<ALength) then
  348. Result:=Result+StringOfChar('0',Alength-L);
  349. end;
  350. Function Soundex(const AText: string): string; // ; ALength: TSoundexLength = 4
  351. begin
  352. Result:=Soundex(AText,4);
  353. end;
  354. Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
  355. begin
  356. NotYetImplemented(' SoundexInt');
  357. end;
  358. Function SoundexInt(const AText: string): Integer; //; ALength: TSoundexIntLength = 4
  359. begin
  360. NotYetImplemented(' SoundexInt');
  361. end;
  362. Function DecodeSoundexInt(AValue: Integer): string;
  363. begin
  364. NotYetImplemented(' DecodeSoundexInt');
  365. end;
  366. Function SoundexWord(const AText: string): Word;
  367. Var
  368. S : String;
  369. begin
  370. S:=SoundEx(Atext,4);
  371. Writeln('Soundex result : "',S,'"');
  372. Result:=Ord(S[1])-Ord('A');
  373. Result:=Result*26+StrToInt(S[2]);
  374. Result:=Result*7+StrToInt(S[3]);
  375. Result:=Result*7+StrToInt(S[4]);
  376. end;
  377. Function DecodeSoundexWord(AValue: Word): string;
  378. begin
  379. NotYetImplemented(' DecodeSoundexWord');
  380. end;
  381. Function SoundexSimilar(const AText, AOther: string; ALength: TSoundexLength): Boolean;
  382. begin
  383. NotYetImplemented(' SoundexSimilar');
  384. end;
  385. Function SoundexSimilar(const AText, AOther: string): Boolean; //; ALength: TSoundexLength = 4
  386. begin
  387. NotYetImplemented(' SoundexSimilar');
  388. end;
  389. Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;
  390. begin
  391. NotYetImplemented(' SoundexCompare');
  392. end;
  393. Function SoundexCompare(const AText, AOther: string): Integer; //; ALength: TSoundexLength = 4
  394. begin
  395. NotYetImplemented(' SoundexCompare');
  396. end;
  397. Function SoundexProc(const AText, AOther: string): Boolean;
  398. begin
  399. NotYetImplemented(' SoundexProc');
  400. end;
  401. end.