[Delphi] ValueListEditor z tekstu

0

Mam o to taki przykładowy tekst:

[ [ [ "komputery", "Klawiatura", 49 ], [ "komputery", "Monitor", 499 ], [ "komputery", "Myszka", 34 ] ] ]

Muszę to rozłożyć na dwie tabele: "Produkt" i "Cena", czyli w Produkt będzie np. "Klawiatura" w Cena "49". Słowa "komputery" mają być zignorowane. Jak taki tekst rozłożyc na tabele? Znalazłem komponent ValueListEditor i on chyba do tego będzie dobry, lecz jeżeli inny też będzie pasował i tak wyglądał to może być.

Lista ma się tylko wyświetlać, bez możliwości edycji. Więc jak te dane poprawnie wyświetlić? Szukałem sporo na ten temat, i znalazłem informacje jak dodać dane itp, ale nie mam pojęcia jak odpowiednio rozszyfrować ten tekst z danymi.

0

najlepszym wyjściem byłyby wyrażenia regularne

\[(\[\"[a-zA-Z]+\",\"([a-zA-Z]+)\",([0-9]+)\],?)+\]

w delphi jest TPerlRegEx i TRegEx bodajże

0

Niestety nic z tego nie rozumiem, ale dzięki za chęć pomocy :(

Szukałem o tych komponentach i nie znalazłem nic co mogło by mi pomóc. Jak dodać te informacje do tabelki za pomocą tego dziwnego kodu?

0

np:

var
    RegEx : TPerlRegEx;
    Stuff : TStringList;
begin
    RegEx := TPerlRegEx.Create(nil);
    Stuff := TStringList.Create;
    Try
        RegEx.RegEx := '\[\"[a-zA-Z]+\",\"([a-zA-Z]+)\",([0-9]+)\]';
        RegEx.Subject := '[[["komputery","Klawiatura",49],["komputery","Monitor",499],["komputery","Myszka",34]]]';
        
        If RegEx.Match then begin
            repeat
                for i := 1 to regex.SubExpressionCount do begin
                    Stuff.Add(regex.SubExpressions[i]);
                end;
            until not RegEx.MatchAgain;
 
            For I := 0 to Stuff.Count - 1 do begin
                Memo1.Lines.Add(Stuff[I]);
            end;
 
        end else begin
            Memo1.Lines.Add('Not found');
        end;
 
    Finally
        RegEx.Free;
        Stuff.Free;
    End;
End;

tu masz inne przykłady zastosowywania tych class http://www.fredshack.com/docs/delphi.html

0

Niestety nie działa mi ten komponent. Pobrałem go z 2 źródeł, zainstalowałem w delphi 7 i 2007, lecz ciągle nic. Po odpaleniu programu nic się nie dzieje, aplikacja się nie pokazuje, a w takim jednym okienku kompilatora widzę coś o "wait kernel".

Skąd mam pobrać ten komponent by działało, lub jakiego innego użyć?

0

Może jest inny sposób na tą tabelkę? Bez tego perla? Może coś na warunkach i pętlach?

0

na maxa prowizoryczne i nieodporne na zmiane budowy stringa (np jedna spacja wiecej lub mniej) ale moze Ci sie spodoba ;]

procedure TForm1.Button1Click(Sender: TObject);
var s:String;
    key,val:string;
    tmp:TStringList;
    i:integer;
begin
s:='[ [ [ "komputery", "Klawiatura", 49 ], [ "komputery", "Monitor", 499 ], [ "komputery", "Myszka", 34 ] ] ]';
tmp:=TStringList.Create;
s:=StringReplace(s, '"komputery"', '', [rfReplaceAll]);
s:=StringReplace(s, '],', #13#10, [rfReplaceAll]);
s:=StringReplace(s, ' [ , ', '', [rfReplaceAll]);
s:=StringReplace(s, ' ] ] ]', '', [rfReplaceAll]);
s:=StringReplace(s, '[ [', '', [rfReplaceAll]);
s:=StringReplace(s, '", ', #13#10, [rfReplaceAll]);
s:=StringReplace(s, '"', '', [rfReplaceAll]);
tmp.Text:=s;
i:=0;
while i<tmp.Count do
     begin
      key:=tmp[i];
      val:=tmp[i+1];
      ValueListEditor1.InsertRow(key,val,true);
      i:=i+2;
     end;

tmp.Free;
end;

//rany az sie wstydze tego kodu... ale powiedzmy ze jest pozno.

0

Nie wiem czy Pecet sprawdził do końca swój kod jeżeli chodzi o zadane wyrażenie, ale to nie do końca, no
a przynajmniej u mnie działało. Ja polecam poniższy kod. A do wyrażeń regularnych użyć raczej modułu,
co zwie się TRegExpr. Działa pod każdym Delphi począwszy od wersji 3. Póki co jego oficjalna strona leży,
ale można na spokojnie pobrać go z mojego konta rapid. także nie trzeba się spieszyć, bo link nie wygaśnie.
A w paczce poza modułem, który należy dodać do sekcji uses jest także dokumentacja, a także przykłady.
Co do tego czy można to zrobić na warunkach. Pewnie i można, ale do parsowania tekstow i uzyskiwania
z nich tego co się chce najlepiej używać właśnie wyrażeń regularnych, no bo do tego są one stworzone :)
http://rapidshare.com/files/306114902/regexpr.rar
Przykładowy kod - sprawdzony działa jak trzeba. Przerobić tylko sobie musisz aby zwracal Ci przykładowo
dane w postaci rekordu z nazwą oraz ceną i dodawał co trzeba do osobnych tabel, czy do czego chcesz :)
Nie wiem czy potrzebne jakieś wyjaśnienia \x20 to znak o kodzie szestnastkowym 20 czyli jest to spacja.

function AbraKadabra(const Tekst : string) : string;
const
  Wzorzec = '\[\x20"(.+?)"\,\x20"(.+?)"\,\x20([0-9]+)\x20\]';
var
  R : TRegExpr;
begin
  Result := '';
  R := TRegExpr.Create;
  try
    R.Expression := Wzorzec;
    if R.Exec(Tekst) then
      repeat
        Result := Result + 'Nazwa: ' + R.Match[2] + ' Cena: ' + R.Match[3] +#13#10;
      until not R.ExecNext;
  finally
    R.Free;
  end;
end;

Sam sprawdzisz jak działa. Umieść na formatce dwa Memo o nazwach Memo1 oraz Memo2 i do Memo1
wklej kod swojej tabelki. Dodając paski przewijania jakby się tekst nie mieścił. wykonaj kod, a w Memo2
otrzymasz to co chciałeś. Więcej przykładów wyrażeń regularnych sobie bez trudu możesz wygooglować.

  Memo2.Text := AbraKadabra(Memo1.Text);

EDIT: no tak cimak mnie ubiegł jak zacząłem pisać post i testować rozwiązanie pod IDE. Jednak jak sam
napisał - sposób nieodpoery na zmiane struktury stringa. Ja jednak jestem za wyrażeniami regularnymi,
bo zdarzyć się może tak, że zamiast słowa Komputer będzie coś innego później, a wyrażenie regularne
jest na to odporniejsze. Łatwiej je też zmienić dzięki edycji jednej linijki - jeżeli zajdzie taka potrzeba.

0

Wielkie dzięki Wam, uzyskałem to co chciałem.
Pozdrawiam!

1 użytkowników online, w tym zalogowanych: 0, gości: 1