Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Stringfilter (https://www.delphipraxis.net/136298-stringfilter.html)

blooddog_90 27. Jun 2009 16:55


Stringfilter
 
Guten Tag alle zusammen :lol:

Ich bin auf der Suche nach einer Möglichkeit, die es mir erlaubt mehrere Strings zu filtern.
Sowas braucht man zum Beispiel bei Namensvorschriften.

Wenn es in einem Programm also nicht erlaubt ist, bei der Eingabe Leerzeichen, Tabs oder Umlaute zuverwenden.

Also dachte ich mir, da gibt es doch bestimmt irgendwas, was mir einen String daraufhin überprüft ob eines dieser Zeichen vorhanden ist. Gibt es denn sowas auch?

Code Schnipsel die mir dazu einfallen (aka Pseudocode):

Delphi-Quellcode:
var
sWort: string;
bContains: boolean;
aStrings: array [0..4] of string;

begin
aStrings := (' ','_','Ä','-');
sWort := edit1.text;
bContains := FilterFunction(sWort,aStrings);
end;
Und ich suche eben jetzt nach einer Function, die mir sowas erledigt wie "FilterFunction" und einen Wahrheitswert zurückliefert. Existiert sowas bereits?

[edit=mkinzler]Delphi-Tag eingefügt Mfg, mkinzler[/edit]

polarwolf 27. Jun 2009 17:29

Re: Stringfilter
 
Da du geschrieben hast Namensvorschriften. Ich habe es mal so probiert.

Delphi-Quellcode:
function Filter(text: string):Boolean;
var
  i:integer;
  Buchstabe:string;
begin
  result:=false;
  for i := 1 to Length(text) do
  begin
    Buchstabe:=(Copy (text, i, 1));
    if Buchstabe = 'Ä' then
    begin
      result:=true;
      break;
    end;
  end;
end;
Aufruf:

Delphi-Quellcode:
Filter(text);
Wenn meine wege doch meistens umständlich sind. sie funktionieren wenigstens.
hat jemand dafür eine schönere Funktion ?

Oreaden 27. Jun 2009 17:43

Re: Stringfilter
 
Wie wär es damit?
Delphi-Quellcode:
function f(s, a: string): boolean;
var
  c: char;
begin
  result := false;
  if (length(s) = 0) or (length(a) = 0) then exit;
  for c in s do
    if pos(c, a) > 0 then
    begin
      result := true;
      exit;
    end;
end;

Aphton 27. Jun 2009 17:47

Re: Stringfilter
 
Delphi-Quellcode:
// Code
procedure FilterText( var Text: String; const BadChars: Array of Char );
var
  i, j: Integer;
  x: Boolean;
begin
  i := 1;
  while i <= Length( Text ) do
  begin
    x := True;
    for j := 0 to High(BadChars) do
      if Text[i] = BadChars[j] then
      begin
        while Text[i] = BadChars[j] do
          Delete( Text, i, 1 );
        x := False;
      end;
    if x then
      inc( i );
  end;
end;

// Beispielsaufruf
  str := '-;:#TestString Blabla #@';
  FilterText( str, [ '-', ',', ':', '#', '@' ] );

himitsu 27. Jun 2009 19:45

Re: Stringfilter
 
Delphi-Quellcode:
procedure FilterText( var Text: String; BadChars: Set of Char );
var
  i: Integer;
begin
  for i := Length(Text) downto 1 do
    if Text[i] in BadChars then
      Delete(Text, i, 1);
end;
Aufruf wie schon bei Aphton

Lannes 27. Jun 2009 20:50

Re: Stringfilter
 
Hallo,

Du könntest die Zeichen auch schon bei der Eingabe ausschließen.

Oreaden 27. Jun 2009 21:41

Re: Stringfilter
 
Seit gegrüßed himitsu,

Ihr wießed doch, dass Eurer Code nur bis D2007 gültig ist, da ein Char ab D2009 mehr als 255 Bits umfassen kann...

Schöne Grüße
Oreaden

Dipl Phys Ernst Winter 27. Jun 2009 21:56

Re: Stringfilter
 
"Oreaden"
Zitat:

function f(s, a: string): boolean;
Sehr aussagekräftig! Ich kann mir darunter jede Funktion zum testen eines Strings vorstellen.

Oreaden 27. Jun 2009 22:00

Re: Stringfilter
 
Zitat:

Zitat von Dipl Phys Ernst Winter
"Oreaden"
Zitat:

function f(s, a: string): boolean;
Sehr aussagekräftig! Ich kann mir darunter jede Funktion zum testen eines Strings vorstellen.

juten morgen Ernst Winter,

yep, der bezug geht aus dem kontext hervor. wenn die funktion jedoch ohne kontext in der lib abgelegt wird, so wie deine vorschläge dann tut man sich mit der interpretation doch sehr schwer. daher war meine bitte an dich, es auch zu dokumentieren...

hier habe ich bewusst, deinen style genommen um zu zeigen, dass die kürze und prägnanz der funktion nicht nur vorteile hat.

einfach mal zum nachdenken.

Oreaden

Neutral General 28. Jun 2009 01:21

Re: Stringfilter
 
Zitat:

Zitat von Oreaden
Seit gegrüßed himitsu,

Ihr wießed doch, dass Eurer Code nur bis D2007 gültig ist, da ein Char ab D2009 mehr als 255 Bits umfassen kann...

Schöne Grüße
Oreaden

Da mir grad langweilig ist... 255 Bits = fast 32 Bytes. Selbst in Delphi 2009 ist ein Char nur 2 Bytes groß ;)

Medium 28. Jun 2009 02:47

Re: Stringfilter
 
@Oreaden: Und um dein Exempel zu statuieren bietest du dem Fragesteller hier übertrieben minimalistischen Code an (der Funktionsname sticht hier schon besonders hervor), wobei er mit recht großer Wahrscheinlichkeit die andere Diskussion garnicht kennt? Da wurde der Disput wohl auf dem falschen Rücken weiter ausgetragen, oder? Das finde ich ist schon eher etwas zum nochmal drüber nachdenken.
Das ist übrigens ein gutes Beispiel für das, was ich in dem anderen Thread mit "Maß halten" meinte. Das gilt nämlich für beide Extreme.
Zudem ist der Kontext hier nicht so weit definiert (mathematische Symbolik vs. "es geht um Strings"), als dass man von allgemein verständlichen Konventionen ausgehen könnte. Oder haben "f", "s" und "a" in der String-Theorie (:stupid:) eine feste Bedeutung?
(Wobei ich jedoch gern zugeben möchte, dass die Kürze der Funktion eine einfache Symbolik begünstigt. Der Funktionsname ist hier mein eigentlicher Stein des Anstoßes.)

Aphton 28. Jun 2009 04:44

Re: Stringfilter
 
Zitat:

Zitat von himitsu
Delphi-Quellcode:
procedure FilterText( var Text: String; BadChars: Set of Char );
var
  i: Integer;
begin
  for i := Length(Text) downto 1 do
    if Text[i] in BadChars then
      Delete(Text, i, 1);
end;
Aufruf wie schon bei Aphton

Wie dumm von mir ... :oops:

Mir sind die "Set of" Dinger nicht eingefallen :P

Himitsu, so wie du das aber programmiert hast, wirds nicht funzn..
Hab ein wenig damit rumgespielt:

Delphi-Quellcode:
type
  TSetOfChar = Set of Char;

//--

procedure FilterText( var Text: String; const BadChars: TSetOfChar );
var
  i: Integer;
begin
  for i := Length(Text) downto 1 do
    if Text[i] in BadChars then
      Delete(Text, i, 1);
end;

Oreaden 28. Jun 2009 09:13

Re: Stringfilter
 
Zitat:

Zitat von Medium
Zudem ist der Kontext hier nicht so weit definiert (mathematische Symbolik vs. "es geht um Strings"), als dass man von allgemein verständlichen Konventionen ausgehen könnte. Oder haben "f", "s" und "a" in der String-Theorie (:stupid:) eine feste Bedeutung?
(Wobei ich jedoch gern zugeben möchte, dass die Kürze der Funktion eine einfache Symbolik begünstigt. Der Funktionsname ist hier mein eigentlicher Stein des Anstoßes.)

hallo medium,

in welchem bereich bist du tätig?

ja, die bezeichnungen sind eindeutig, f() = eine funktion, s = source/string und a ist das array oder parameter... o.k. den parameter hätt ich wohl besser p bezeichnen sollen...

wo liegt das problem? es geht doch hier nur um eine funktion... die braucht man doch nicht durchnummerieren...

btw: geht doch der ganze thread nur um einen filter... weshalb muss man da dann 1000 das gleiche hinschreiben... ist irgendwie zu mühsamm...

schöne grüsse vom orakel
Oreaden

btw: die informatik hat sich auch von der mathematik abgespalten... somit verstehe ich nicht, was du hier meinst mit stringtheorie und mathematik...

alzaimar 28. Jun 2009 09:56

Re: Stringfilter
 
So Leute, nachdem wir uns ja im Thread zum Thema 'Horner-Schema' ausreichend mit dem Sinn und Unsinn von Namens- und Formatierungskonventionen augelassen haben, schlage ich vor, das diejenigen, die weiterhin darüber diskutieren wollen, sich entweder in eine Kneipe ihrer Wahl verdünnisieren oder einen separaten Thread aufmachen, um sachlich über dieses an sich sehr wichtige Thema zu diskutieren.

Hier sollte es nur noch um eine Filterfunktion gehen, die entweder unerwünschte Zeichen aus einem String entfernt, oder prüft, ob ein String ungültige Zeichen enthält. Es gibt bezüglich der vorgestellten Funktionen genug Diskussionsstoff (Performance, Eleganz, Allgemeingültigkeit etc.)

himitsu 28. Jun 2009 10:19

Re: Stringfilter
 
ich frag mich sowieso wieso ein Set of WideChar nicht geht ... wären doch nur 8 KB, aber da eh nicht alle Unicode nutzen und man ja nicht unbedingt alles auf Unicode umbrechen muß ...

so wäre es dann unicodetauglich und es würden alle Zeichen entfernt, welche in BadChars dinn sind und nicht in ANSI reinpassen, egal welche Codierung ANSI hatt :nerd:
Delphi-Quellcode:
procedure FilterText(var Text: String; const BadChars: TSysCharSet);
var
  i: Integer;
begin
  for i := Length(Text) downto 1 do
    if (Text[i] in BadChars) or not (Text[i] in [#$0000..#$00FF]) then
      Delete(Text, i, 1);
end;

// bzw.

procedure FilterText(var Text: String; const BadChars: TSysCharSet);
var
  i: Integer;
begin
  for i := Length(Text) downto 1 do
    if (Text[i] in BadChars) or (Text[i] > #$00FF) then
      Delete(Text, i, 1);
end;
eigentlich müßte Ersteres eher stimmen, aber es scheint mit Letzterem übereinzustimmen ... schon eigenartig :shock:

[add]
so sollte es dann keine Wiedersprüche geben :angel2:
Delphi-Quellcode:
procedure FilterText(var Text: String; BadChars: TSysCharSet);
var
  i: Integer;
begin
  BadChars := [#$0000..#$00FF] - BadChars;
  for i := Length(Text) downto 1 do
    if not (Text[i] in BadChars) then
      Delete(Text, i, 1);
end;

Oreaden 28. Jun 2009 11:34

Re: Stringfilter
 
@himitsu: mhhh, 'ne ansi funktion... hier mal etwas, was auch chinesische zeichen ordentlich rausfiltert... ;-9

Delphi-Quellcode:
procedure f(var s, p: string);
var
  x: string;
  c: char;
  i: integer;
begin
  if (length(s) = 0) or (length(p) = 0) then exit;
  x := s;
  s := EmptyStr;
  setlength(s, length(x));
  i := 0;
  for c in x do
    if pos(c, p) = 0 then
    begin
      inc(i);
      s[i] := c;
    end;
  setlength(s, i);
end;
ob's jemand braucht, ist 'ne andere frage :stupid:

btw: TSysCharSet = set of ansichar

Popov 28. Jun 2009 11:37

Re: Stringfilter
 
Dieser Code ersetzt alle verbotenen Zeichen durch ein Ersatzzeichen:

Delphi-Quellcode:
const
  VerboteneZeichen = 'äÄöÖüÜß: !';
  ErsatzZeichen = '_';
var
  s: String;
  c: Char;
  i: Integer;
begin
  s := 'Müller sagte: Hallo Welt!'; //der Satz

  ShowMessage('Original: ' + s);

  for i := 1 to Length(VerboteneZeichen) do
  begin
    c := VerboteneZeichen[i]; //immer nur ein Zeichen

    while Pos(c, s) > 0 do
      s[Pos(c, s)] := ErsatzZeichen;
  end;

  ShowMessage('Verändert: ' + s);
end;

Popov 28. Jun 2009 11:49

Re: Stringfilter
 
Hier eine Funktion die ich mal zur Überprüfung von Pfaden geschrieben habe:

Delphi-Quellcode:
function IsValidPath(s: String): Boolean;
var
  i: Integer;
  t: String;
begin
  Result := False;

  if Length(s) < 1 then Exit;
  if s[Length(s)] <> '\' then s := s + '\';
  if not (((s[1] in ['a'..'z', 'A'..'Z']) and (Copy(s, 2, 2) = ':\')) or
    (Copy(s, 1, 2) = '\\')) then Exit;
  if Copy(s, 1, 2) = '\\' then Delete(s, 1, 2) else Delete(s, 1, 3);

  while Length(s) > 0 do begin
    t := Copy(s, 1, Pos('\', s) - 1);
    if t = '' then Exit;
    for i := 1 to Length(t) do if Pos(t[i], '\/:*?"<>|') > 0 then Exit;
    Delete(s, 1, Pos('\', s));
  end;

  Result := True;
end;
Ist schon paar Jahre alt, aber ich denke, daß sie funktionierte.

Übrigens, wenn du eine Funktion suchst die überprüft ob Bezeichner aus diesen Buchstaben besteht: 'A'..'Z', 'a'..'z', '0..'9', '_', dann gibt es bereits eine fertige Funktion:

Delphi-Quellcode:
  if not IsValidIdent(s) then ...

Popov 28. Jun 2009 12:00

Re: Stringfilter
 
Hier noch etwas allgemeines, aus meiner Funktionskiste:

Delphi-Quellcode:
function IsValidStr(s: String): Boolean;
const
  ValidChars = ['0'..'9', 'A'..'Z', 'a'..'z'];
var
  i: Integer;
begin
  Result := False;

  if Length(s) < 1 then Exit;
  for i := 1 to Length(s) do
    if not (s[i] in ValidChars) then Exit;

  Result := True;
end;
Welche Zeichen erlaubt sind steht in ValidChars.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz