What is the fastest way of stripping non alphanumeric characters from a string in Delphi7?
Asked Answered
Y

4

5

The characters allowed are A to Z, a to z, 0 to 9. The least amount of code or a single function would be best as the system is time critical on response to input.

Yearbook answered 22/2, 2009 at 8:55 Comment(0)
K
10
uses JclStrings;

  S := StrKeepChars('mystring', ['A'..'Z', 'a'..'z', '0'..'9']);
Kamasutra answered 8/6, 2009 at 20:38 Comment(1)
Note: In the latest JCL library, you would say: uses JclAnsiStringsFade
T
11

If I understand you correctly you could use a function like this:

function StripNonAlphaNumeric(const AValue: string): string;
var
  SrcPtr, DestPtr: PChar;
begin
  SrcPtr := PChar(AValue);
  SetLength(Result, Length(AValue));
  DestPtr := PChar(Result);
  while SrcPtr[0] <> #0 do begin
    if SrcPtr[0] in ['a'..'z', 'A'..'Z', '0'..'9'] then begin
      DestPtr[0] := SrcPtr[0];
      Inc(DestPtr);
    end;
    Inc(SrcPtr);
  end;
  SetLength(Result, DestPtr - PChar(Result));
end;

This will use PChar for highest speed (at the cost of less readability).

Edit: Re the comment by gabr about using DestPtr[0] instead of DestPtr^: This should compile to the same bytes anyway, but there are nice applications in similar code, where you need to look ahead. Suppose you would want to replace newlines, then you could do something like

function ReplaceNewlines(const AValue: string): string;
var
  SrcPtr, DestPtr: PChar;
begin
  SrcPtr := PChar(AValue);
  SetLength(Result, Length(AValue));
  DestPtr := PChar(Result);
  while SrcPtr[0] <> #0 do begin
    if (SrcPtr[0] = #13) and (SrcPtr[1] = #10) then begin
      DestPtr[0] := '\';
      DestPtr[1] := 't';
      Inc(SrcPtr);
      Inc(DestPtr);
    end else
      DestPtr[0] := SrcPtr[0];
    Inc(SrcPtr);
    Inc(DestPtr);
  end;
  SetLength(Result, DestPtr - PChar(Result));
end;

and therefore I don't usually use the ^.

Titfer answered 22/2, 2009 at 10:5 Comment(6)
I find the use of SrcPtr[0] here highly interesting - never seen such approach before. More canonical way would be to use SrcPtr^ and DestPtr^.Russ
Re: Formatting - maybe if you put the missing semicolon in after "DestPtr[0] := 't'" the highlighting would work. :-)Rinehart
Thanks Ken, corrected, but it's still not working :-( The highlighter treats Delphi strings as C strings unfortunately.Titfer
@mghie: RE Edit: That's really neat approach and something that I never thought of. Thanks for the great idea!Russ
I think you mean to say while SrcPtr^ <> #0 or while SrcPtr[0] <> #0.Fade
Note that Delphi strings may contain null characters. The result of calling S := 'A string with a null '#0' character!'; T := StripNonAlphaNumeric ( S ); will end with an l.Fade
K
10
uses JclStrings;

  S := StrKeepChars('mystring', ['A'..'Z', 'a'..'z', '0'..'9']);
Kamasutra answered 8/6, 2009 at 20:38 Comment(1)
Note: In the latest JCL library, you would say: uses JclAnsiStringsFade
D
3

Just to add a remark.

The solution using a set is fine in Delphi 7, but it can cause some problems in Delphi 2009 because sets can't be of char (they are converted to ansichar).

A solution you can use is:

case key of 
  'A'..'Z', 'a'..'z', '0'..'9' : begin end; // No action
else
  Key := #0;
end;

But the most versatile way is of course:

if not ValidChar(key) then
  Key := #0;

In that case you can use ValidChar in multiple locations and if it need to be changed you only have to change it once.

Dinnage answered 22/2, 2009 at 10:1 Comment(0)
E
0

OnKeypress event

begin if not (key in ['A'..'Z','a'..'z','0'..'9']) then Key := #0; end;

Ermines answered 22/2, 2009 at 9:20 Comment(1)
You have to validate text before using anyway. You can bypass this check using clipboard or text drag&drop.Rathbun

© 2022 - 2024 — McMap. All rights reserved.