Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Alle Buchstaben entfernen


Kri - So 28.12.08 03:27
Titel: Alle Buchstaben entfernen
Hallo zusammen,

ich würde gerne aus einem Editfeld alles außer Zahlen und Punkten(.) entfernen.
Leider bin ich mir nicht ganz bewusst wie ich das machen soll.

Habe mir einen Ansatz überlegt:

Delphi-Quelltext
1:
var  Alphabet : array[0..25of Char;                    

und

Delphi-Quelltext
1:
Edit2.Text:=StringReplace(Edit1.Text, Alphabet, '', [rfReplaceAll]);                    


Leider komme ich an dieser Stelle nicht weiter.


Viele liebe Grüße
Kri


JayEff - So 28.12.08 03:36

Naja, einfach das Array durchlaufen und den aktuellen Buchstaben mit '' ersetzen, etwa so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var  Alphabet : array[0..25of Char; //Ich vermute, du hast das Array auch gefüllt, mit den Buchstaben a-z? äöüß ?
{...}
for i := Low(Alphabet) to High(Alphabet) do
begin
  Edit2.Text:=StringReplace(Edit1.Text, LowerCase(Alphabet[i]), '', [rfReplaceAll]); //klein- und großbuchstaben
  Edit2.Text:=StringReplace(Edit1.Text, UpperCase(Alphabet[i]), '', [rfReplaceAll]);
end;


Das array kannst du dir aber sparen und stattdessen per Char(Ord(a) + i)) auf die Buchstaben zugreifen. äöüß sind hierbei natürlich sonderfälle, ebenso wie á ô etc.


jaenicke - So 28.12.08 03:36

Willst du nicht eher erreichen, dass nur Zahlen eingegeben werden können?
Wie wäre es dann, wenn du die Eingabe aller anderen Zeichen gleich verhinderst? Das könntest du in OnKeyPress machen, wie es in dem entsprechenden Eintrag in der Library steht:
http://www.delphi-library.de/viewtopic.php?p=48510
Variante 4 ist vermutlich die passende.


Kri - So 28.12.08 03:49

Hallo zusammen,

danke für die Antworten..
Okay.. Das Array habe ich nicht gefüllt.. Ich bin Arrays bis jetzt immer geschickt umgangen, hier besteht aber glaube ich die Notwendigkeit.. Gibt es nicht so etwas wie alles außer '0'..'9' und '.'?

Der Text wird via CopyPaste in das Edit eingefügt, daher kommt jaenickes Vorschlag leider nicht in Frage.


Viele liebe Grüße
Kri


jaenicke - So 28.12.08 03:53

Wie wäre es so?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
  i: Integer;
  MyString: String;
begin
  MyString := Edit1.Text;
  i := 1;
  while i <= Length(MyString) do
    if MyString[i] in ['0'..'9''.'then
      Inc(i)
    else
      Delete(MyString, i, 1);
  Edit2.Text := MyString;
;-)

// EDIT:
Ach ja:
user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
for i := Low(Alphabet) to High(Alphabet) do
begin
  Edit2.Text:=StringReplace(Edit1.Text, LowerCase(Alphabet[i]), '', [rfReplaceAll]); //klein- und großbuchstaben
  Edit2.Text:=StringReplace(Edit1.Text, UpperCase(Alphabet[i]), '', [rfReplaceAll]);
end;
Du ersetzt jedesmal den ursprünglichen Text aus Edit1 und packst jedes Ergebnis in Edit2, d.h. am Ende steht in Edit2 das Ergebnis der letzten Ersetzung, mehr nicht. ;-)
(Mal abgesehen davon, dass es unnötig kompliziert ist. ;-))


Kri - So 28.12.08 04:08

Hallo jaenicke,

vielen vielen Dank für deine Hilfe, das ist die Lösung!
Großes Lob an dich, mitten in der Nacht und trotzdem verdammt schnell unterwegs :-P


Viele liebe Grüße
Kri


Delete - So 28.12.08 12:09

Ich hätte da auch noch einen Vorschlag:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function NumbersOnly(const s: AnsiString): AnsiString;
var i,j: integer;
begin
  SetLength(Result,Length(s));
  j := 0;
  for i := 1 to Length(s) do
    if s[i] in ['0'..'9','.'then
      begin
        inc(j);
        Result[j] := s[i];
      end;
  SetLength(Result,j);
end;


jaenicke - So 28.12.08 14:49

Na, wenn schon Optimierung, dann richtig:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function NumbersOnly(const s: AnsiString): AnsiString;
var
  i: integer;
  CurrentChar: ^Char;
begin
  SetLength(Result, Length(s));
  CurrentChar := Pointer(Result);
  for i := 1 to Length(s) do
    if s[i] in ['0'..'9','.'then
    begin
      CurrentChar^ := s[i];
      Inc(CurrentChar);
    end;
  SetLength(Result, Integer(CurrentChar) - Integer(Pointer(Result)));
end;
Bei dir wird ja noch bei jedem geschriebenen Buchstaben intern UniqueString aufgerufen. :mrgreen:


Delete - So 28.12.08 14:50

Klugscheißer :mrgreen:


mkinzler - So 28.12.08 14:54

Jetzt muss man nur den zu ersetzenden Text so erweitern, das man die Optimierungen auch spürt! :roll:


Kri - So 28.12.08 16:05

Hallo zusammen,

jaenickes Variante hab ich verstanden, aber was macht DeddyHs Version, kann mir das jemand erklären?


Viele liebe Grüße
Kri


jaenicke - So 28.12.08 16:10

Da wird zuerst die Länge des Ergebnisstrings auf die des ursprünglichen Strings gesetzt (länger kann das Ergebnis ja nicht sein), und dann die einzelnen Buchstaben direkt ins Ergebnis gesetzt.
So wird anders als bei mir nicht immer wieder ein neuer String mit dem neuen Wert erzeugt, denn das passiert bei mir jedes Mal, wenn ein Buchstabe gelöscht wird.
Am Ende wird dann die Länge auf die tatsächliche Länge gesetzt, dafür wurden vorher die eingefügten Zahlen in j gezählt.

Meine optimierte Variante macht im Prinzip das selbe, nur dass ich direkt auf die Speicherstelle mit dem entsprechenden Zeichen zugreife um zu verhindern, dass Delphi vorher den String ggf. mit UniqueString kopiert um sicherzustellen, dass evtl. existierende Referenzen auf den String den unveränderten String behalten.
Durch den Pointerzugriff erkennt Delphi schlicht die Änderung am String nicht, was die Automatik umgeht und das etwas schneller macht.


Kri - So 28.12.08 16:24

Hallo jaenicke,

danke für deine Antwort! Hab das gerade mal ausprobiert und muss leider zurückmelden dass es nicht funktioniert. Buchstaben werden trotzdem übernommen.

EDIT:

Delphi-Quelltext
1:
2:
3:
MyString:=Edit1.Text;
NumbersOnly(MyString);
Edit2.Text:=MyString;



Viele liebe Grüße
Kri


Delete - So 28.12.08 16:27


Delphi-Quelltext
1:
Edit2.Text := NumbersOnly(Edit1.Text);                    

Das ist ja auch eine Funktion ;)


Kri - So 28.12.08 16:30

Hallo DeddyH,

natürlich, entschuldige :oops:
Danke.


Viele liebe Grüße
Kri