Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   String in einer Stringliste an Trennzeichen zerlegen (https://www.delphipraxis.net/200636-string-einer-stringliste-trennzeichen-zerlegen.html)

Trafel21 16. Mai 2019 09:01

AW: String in einer Stringliste an Trennzeichen zerlegen
 
Kann ich als Trennzeichen auch #13#10 verwenden ?

Bspw.:

Code:
Event: DialBegin
Privilege: call,all
Channel: PJSIP/1177-00000638
ChannelState: 4
ChannelStateDesc: Ring
CallerIDNum: 1177
CallerIDName: IT Test
ConnectedLineNum:
ConnectedLineName:
Language: de
AccountCode:
Context: macro-dial
Exten: s
Priority: 65
Callid: 1022539411-5060-31@BA.BHC.CF.BCA
Linkedid: 1557992134.3754
PageFlag: false
Application: Dial
Reg_calleenum:
Reg_callernum:
Reg_callername:
Uniqueid: 1557992134.3754
DestChannel: PJSIP/1126-00000639
DestChannelState: 0
DestChannelStateDesc: Down
DestCallerIDNum: 1126
DestCallerIDName: Martin
DestConnectedLineNum: 1177
DestConnectedLineName: IT Test
DestLanguage: de
DestAccountCode:
DestContext: callee-handler
DestExten: s
DestPriority: 12
DestCallid: b8fad6fc-4053-4b2d-ad90-13773452ebe2
DestLinkedid: 1557992134.3754
DestPageFlag: false
DestApplication: Set
DestReg_calleenum:
DestReg_callernum:
DestReg_callername:
DestUniqueid: 1557992135.3755
DialString: 1126/sip:1126@10.172.25.125:5060

Event: NewConnectedLine
Privilege: call,all
Channel: PJSIP/1177-00000638
ChannelState: 4
ChannelStateDesc: Ring
CallerIDNum: 1177
CallerIDName: IT Test
ConnectedLineNum: 1126
ConnectedLineName: Martin
Language: de
AccountCode:
Context: macro-dial
Exten: s
Priority: 65
Callid: 1022539411-5060-31@BA.BHC.CF.BCA
Linkedid: 1557992134.3754
PageFlag: false
Application: Dial
Reg_calleenum:
Reg_callernum:
Reg_callername:
Uniqueid: 1557992134.3754
Ich möchte die Events auch trennen. In dem Buffer können beliebig viele Events kommen, mal 1 oder mal 4. D.h. ich müsste es irgendwie mit einer eof schleife durchgehen oder?

Bei Trim(Eventlst.Values['Event']); nimmt dieser nur das 1. Event auf, nicht das 2. oder evtl 3. oder 4. Gibt es eine Möglichkeit an die auch zu kommen?

Klaus01 16. Mai 2019 09:09

AW: String in einer Stringliste an Trennzeichen zerlegen
 
.. für die StringList ist #13#10 die Markierung um eine neue Zeile anzulegen.
Als Delimiter kann man meines Wissens nur ein Zeichen verwenden.

trim kannst Du dann auf die einzelen Zeilen der StringList anwenden.

Grüße
Klaus

Uwe Raabe 16. Mai 2019 09:50

AW: String in einer Stringliste an Trennzeichen zerlegen
 
Zitat:

Zitat von Trafel21 (Beitrag 1432316)
Bei Trim(Eventlst.Values['Event']); nimmt dieser nur das 1. Event auf, nicht das 2. oder evtl 3. oder 4. Gibt es eine Möglichkeit an die auch zu kommen?

Dann musst du die StringList manuell mit jeweils nur einem Block füllen und danach wieder leer machen. Z.B. so:
Delphi-Quellcode:
procedure HandleData(Source: TStrings);
var
  CallerID: string;
  EventName: string;
begin
  if Source.Count = 0 then Exit;

  EventName := Trim(Source.Values['Event']);
  CallerID := Trim(Source.Values['CallerIDNum']);
end;

procedure HandleFile(const AFileName: string);
var
  line: string;
  lst: TStringList;
  reader: TStreamReader;
begin
  reader := TStreamReader.Create(AFileName);
  try
    lst := TStringList.Create;
    try
      lst.NameValueSeparator := ':';
      while not reader.EndOfStream do begin
        line := reader.ReadLine;
        if Trim(line) = '' then begin
          HandleData(lst);
          lst.Clear;
        end
        else begin
          lst.Add(line);
        end;
      end;
      { falls als letztes keine Leerzeile mehr kam }
      HandleData(lst);
    finally
      lst.Free;
    end;
  finally
    reader.Free;
  end;
end;

Moombas 16. Mai 2019 10:11

AW: String in einer Stringliste an Trennzeichen zerlegen
 
Wozu #13#10 als Trennzeichen verwenden? Dann kannst du doch einfach jede Zeile direkt durchgehen und ausgeben lassen.

Ein Beispiel wie ich es aktuell nutze, mal für dich etwas angepasst. Hab es aber nicht testen können.

Delphi-Quellcode:
procedure Bla.ReadCSVClick(Sender: TObject);
var
  StringList  : TStringList;
  row         : Integer;
  Eventcounter : integer;
begin
  Eventcounter := 0;
  StringList := TStringList.Create;
  try
    StringList.LoadFromFile('Stringlistfile.xxx');
    for row := 0 to StringList.Count - 1 do
    begin
      if split(StringList.Strings[row], ':', 1) = 'Event' then //Wenn ein neues Event kommt;
      begin
        inc(Eventcounter); //definieren des Events
      end;
      //Mache was für das Event "Eventcounter" (Name des Events wäre split(StringList.Strings[row], ':', 2)
    end;
  finally
    StringList.Free;
  end;
end;

//String zerteilen
function Split(text: string; delimiter: char; p: integer): string;
var
  stl: TStrings;
begin
  stl := TStringList.Create;
  try
    stl.delimiter := delimiter;
    stl.DelimitedText := text;
  finally
    result := stl.Strings[p];
    stl.free;
  end;
end;

Trafel21 16. Mai 2019 10:16

AW: String in einer Stringliste an Trennzeichen zerlegen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1432319)
Zitat:

Zitat von Trafel21 (Beitrag 1432316)
Bei Trim(Eventlst.Values['Event']); nimmt dieser nur das 1. Event auf, nicht das 2. oder evtl 3. oder 4. Gibt es eine Möglichkeit an die auch zu kommen?

Dann musst du die StringList manuell mit jeweils nur einem Block füllen und danach wieder leer machen. Z.B. so:
Delphi-Quellcode:
procedure HandleData(Source: TStrings);
var
  CallerID: string;
  EventName: string;
begin
  if Source.Count = 0 then Exit;

  EventName := Trim(Source.Values['Event']);
  CallerID := Trim(Source.Values['CallerIDNum']);
end;

procedure HandleFile(const AFileName: string);
var
  line: string;
  lst: TStringList;
  reader: TStreamReader;
begin
  reader := TStreamReader.Create(AFileName);
  try
    lst := TStringList.Create;
    try
      lst.NameValueSeparator := ':';
      while not reader.EndOfStream do begin
        line := reader.ReadLine;
        if Trim(line) = '' then begin
          HandleData(lst);
          lst.Clear;
        end
        else begin
          lst.Add(line);
        end;
      end;
      { falls als letztes keine Leerzeile mehr kam }
      HandleData(lst);
    finally
      lst.Free;
    end;
  finally
    reader.Free;
  end;
end;

Vom TStreamReader hab ich noch nie gelesen, das hilft mir auf jedenfall weiter, vielen Dank!

freejay 16. Mai 2019 11:47

AW: String
 
Zitat:

Zitat von hoika (Beitrag 1431891)
Hallo,
TStringList
LoadFromFile

und dann die StringList durchlaufen und mit Pos(ZeilenString, 'CallerIDNum: ')=1 die richtige Zeile finden.
Und zum Schluss mit Copy oder StringReplace die Nummer extrahieren.

Ich weiß ja, dass pos ein echter Klassiker ist, aber mittlerweile kann man das dank der String-Helper deutlich eleganter machen. Denn statt

Delphi-Quellcode:
if Pos(ZeilenString, 'CallerIDNum: ')=1 then
kann man folgendes schreiben:

Delphi-Quellcode:
if ZeilenString.StartsWith('CallerIDNum: ') then


Nur mal so zur Erinnerung - auch an mich selbst! :-D

Moombas 16. Mai 2019 12:38

AW: String
 
Zitat:

Zitat von freejay (Beitrag 1432326)
Zitat:

Zitat von hoika (Beitrag 1431891)
Hallo,
TStringList
LoadFromFile

und dann die StringList durchlaufen und mit Pos(ZeilenString, 'CallerIDNum: ')=1 die richtige Zeile finden.
Und zum Schluss mit Copy oder StringReplace die Nummer extrahieren.

Ich weiß ja, dass pos ein echter Klassiker ist, aber mittlerweile kann man das dank der String-Helper deutlich eleganter machen. Denn statt

Delphi-Quellcode:
if Pos(ZeilenString, 'CallerIDNum: ')=1 then
kann man folgendes schreiben:

Delphi-Quellcode:
if ZeilenString.StartsWith('CallerIDNum: ') then
Nur mal so zur Erinnerung - auch an mich selbst! :-D

Das setzt voraus, das er einen speziellen Eintrag finden und den zugehörigen Wert ausgeben möchte. Soll aber immer die ganze Zeile betrachtet werden muss man den Klassiker wählen und die Zeilen durchgehen oder die Variante von Uwe Raabe wählen.

freejay 16. Mai 2019 13:02

AW: String
 
Zitat:

Zitat von Moombas (Beitrag 1432339)
Zitat:

Zitat von freejay (Beitrag 1432326)
Zitat:

Zitat von hoika (Beitrag 1431891)
Hallo,
TStringList
LoadFromFile

und dann die StringList durchlaufen und mit Pos(ZeilenString, 'CallerIDNum: ')=1 die richtige Zeile finden.
Und zum Schluss mit Copy oder StringReplace die Nummer extrahieren.

Ich weiß ja, dass pos ein echter Klassiker ist, aber mittlerweile kann man das dank der String-Helper deutlich eleganter machen. Denn statt

Delphi-Quellcode:
if Pos(ZeilenString, 'CallerIDNum: ')=1 then
kann man folgendes schreiben:

Delphi-Quellcode:
if ZeilenString.StartsWith('CallerIDNum: ') then
Nur mal so zur Erinnerung - auch an mich selbst! :-D

Das setzt voraus, das er einen speziellen Eintrag finden und den zugehörigen Wert ausgeben möchte. Soll aber immer die ganze Zeile betrachtet werden muss man den Klassiker wählen und die Zeilen durchgehen oder die Variante von Uwe Raabe wählen.

In dem von mir zitierten Beispiel wird am Zeilenanfang gesucht ("pos(...)=1"): Darauf bezieht sich mein Kommentar. Dass man, wenn man innerhalb der Zeile sucht, StartsWith nicht verwenden kann, dürfte klar sein...

Trafel21 17. Mai 2019 07:33

AW: String in einer Stringliste an Trennzeichen zerlegen
 
Ich hab mich für einen etwas anderen Weg entschieden. Ohne die Anregungen wäre ich trotzdem nicht darauf gekommen, danke nochmals. :)

Code:
    //Events auslesen (pro Buffer können 1-24 Events eingehen)
    EventCounter := 0;
    for row := 0 to (lst.Count -1) do
    begin
      if ((lst.Strings[row]).StartsWith('Event')) then
      begin
        if(Eventlst.Count = 0) then // Nur beim 1. Event true
        begin
          Eventlst.Add(lst.Strings[row]);
          EventCounter := 1;
        end
        else
        begin
          handleEvent(Eventlst.Text); // Event handeln
          Eventlst.Clear;
          Eventlst.Add(lst.Strings[row]);
          EventCounter := EventCounter+1;
        end;
      end
      else
      begin
        Eventlst.Add(lst.Strings[row]);
      end;
    end;

    // Falls nur 1 Event im Buffer
    if (EventCounter = 1) then
    begin
      handleEvent(Eventlst.Text); // Event handeln
      Eventlst.Clear;
    end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:18 Uhr.
Seite 2 von 2     12   

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