Zum Hauptinhalt springen

Funktionen auf Zeichenketten

Einführung

Zeichenketten (Text, String) können als Teil eines Geräteprotokolls auftreten, z.B. als Fehlermeldung eines Subsystems oder der Messdatenübertragung über eine serielle Schnittstelle. Auch viele WEB-Basierte Kommuniationsprotokolle bauen auf Strings auf.

Das Mathemodul unterstützt den skalaren Typ string, in dem typischerweise mit UTF-8 kodierte Zeichen enthalten sind.

Alle Datentypen können z.B. mit str() in den string-Typ gewandelt werden oder mit den anderen cast-Operatoren in die entsprechenden Zieltypen, sofern dabei keine syntaktischen Fehler auftreten.

Operatoren auf Text

Mit dem Datentyp String werden folgende Operatoren unterstützt:

  • alle Vergleichsoperatoren, dabei gilt die numerische Reihenfolge der ASCII-Zeichen: z.B. '4' < 'A' < 'a'

  • + - Operator, verknüpft zwei Strings

    s_connected = s1 + s2;
    tipp

    str(x) wandelt jeden Datentyp in eine String-Darstellung, auch Mehrdimensionale Objekte wie Vektoren und Matrizen. Um mehr Kontrolle über die Formatierung zu bekommen, kann die Funktion sFormat(f, ...) hilfreich sein.

Eigenschaften und Basisfunktionen

Länge einer Zeichenkette "sLength"

Die Länge einer Zeichenkette s in Bytes wird wie folgt berechnet

l = sLength(s);

In der UTF-8 Kodierung können mit entsprechender Kodierung Sonderzeichen auch mehrere Bytes belegen. Diese Funktion bestimmt die Anzahl der Bytes, nicht die Anzahl der (druckbaren) Zeichen!

Extraktion einer Teilzeichenkette als Kopie "sCopy"

Ein Teilstring r des Strings s kann wie folgt extrahiert werden

r = sCopy(s, b);        //  Kopie der Zeichenkette s ab Position b
r = sCopy(s, b, c); // Kopie der Zeichenkette s ab Position b der Länge c
r = sCopy(s, BC); // BC ist ein Vektor der Länge 2, der b und c beinhaltet (Verhalten wie bei sCopy(s, b, c)
r = sCopy(s, BC, sel); // BC ist eine Matrix mit zwei Spalten, die zu b und c korrespondieren,
// wobei sel einen selektierenden Zeilenindex darstellt

Die Matrix BC ist an vielen Stellen das Ergebnis von Suchfunktionen, z.B. sFind(), die mehrere Treffer in dem String liefern können. Über den Index sel kann der entsprechende Textteil unmittelbar extrahiert werden.

Beispiel:

//     0         1         2         3
// 0123456789012345678901234567890123456789
geo = 'lat: 51.234567, lon: 12.3456789';
p6 = sFind(geo, 'lat:\s*([0-9.+-]+)', {subex: true});
// => p6 := [ [ 0,14] // refers to 'lat: 51.234567'
// , [ 5, 9]]; // refers to '51.234567'
lat = dbl(sCopy(geo, p6, 1));
// => lat := 51.234567;

Extraktion des Stringanfangs und -endes "sLeft", "sRight"

Stringanfang b und Stringende e der Länge l des Strings s können wie folgt als Kopie erhalten werden

b = sLeft(s,l);
e = sRight(s,l);

Entfernen eines Teilstrings "sErase"

Um eine Kopie eines Strings s zu erhalten, in der ein Teilstring entfernt wurde, kann folgendes verwendet werden

r = sErase(s, b);        //  Kopie der Zeichenkette s ohne Zeichen ab Position b
r = sErase(s, b, c); // Kopie der Zeichenkette s ohne Zeichen ab Position b der Länge c
r = sErase(s, BC); // BC ist ein Vektor der Länge 2, der b und c beinhaltet (Verhalten wie bei sErase(s, b, c)
r = sErase(s, BC, sel); // BC ist eine Matrix mit zwei Spalten, die zu b und c korrespondieren,
// wobei sel einen selektierenden Zeilenindex darstellt

Die Matrix BC ist an vielen Stellen das Ergebnis von Suchfunktionen, z.B. sFind(), die mehrere Treffer in dem String liefern können. Über den Index sel kann der entsprechende Textteil unmittelbar entfernt werden.

Einfügen eines Strings "sInsert"

Um einen String t innerhalb eines Strings s an Position b einzufügen und eine Kopie r zurückzuliefern, kann folgendes verwendet werden

r = sInsert(s, b, t);

Erzeugen, Formatieren, Lesen, Aufräumen

Extraktion numerischer Werte aus einem String "sScan"

Under Construction Diese Funktion ist in Vorbereitung.

Um numerische Werte aus einem String s zu extrahieren und einen Vektor v dieser Werte zurückzuliefern, kann folgendes verwendet werden

v = sScan(f, s);

Hierbei stellt f einen Formatstring in der Art von scanf() dar.

Formatierung eines Strings "sFormat"

Um einen String f, der z.B. numerische Werte beinhaltet, als String r formatiert darzustellen, kann folgende Funktion benutzt werden

r = sFormat(f, ...);

Hierbei stellt f einen Formatstring in der Art von printf() dar, und es ist zu jedem Platzhalter ein korrespondierendes Argument der Form %[<width>][.<precision>]<type> anzugeben.

  • <width>: optionale Feldbreite für die Ausgabe, width < 0: linksbündig

  • .<precision>: optional für f/g/e, Anzahl der Nachkommastellen oder gültigen Ziffern

  • <type>: Die Argumente werden entsprechend des gewählten Ausgabetyps konvertiert. Zusätzliche Längenangaben für den Datentyp werden deshalb nicht benötigt.

    <type>DatentypAusgabe
    b<bool>Ausgabe von 'false' oder 'true'
    d<int>Ganzzahl mit Vorzeichen, Basis 10
    u<uint>Ganzzahl ohne Vorzeichen, Basis 10
    x, X<uint>Ganzzahl ohne Vorzeichen, Basis 16
    kleine (x) oder große (X) Ziffern A-F
    o<uint>Ganzzahl ohne Vorzeichen, Basis 8
    f<dbl>Fließkommazahl ohne 10er-Exponent
    Beispiel: 1234.5678
    g<dbl>Fließkommazahl in optimierter Darstellung
    wie f oder e je nach Größenordnung der Zahl.
    Beispiele: 1234.45678, 1.2345e9, 1.2345e-12
    e<dbl>Fließkommazahl mit 10er-Exponent
    Beispiel: 1.2345678e3
    s<str>Text

Beispiel:

template = 'alt: %6.2f, lat: %.9f, lon: %.9f';
tx = sFormat(template, 140.4, 49.8765432, -3.14);
// tx := 'alt: 140.40, lat: 49.876543200, lon: -3.140000000';

Zugriff auf den Inhalt einer Ressource "sResource"

Die Funktion liefert den Inhalt der bezeichneten Ressource als konstanten (binären) String.

resStr = sResource({@ref:'myResource'});
warnung

Der Inhalt der Ressource kann je nach Konfiguration nicht nur reinen UTF-8-Text beinhalten (z.B. eine INI-Datei oder ein JSON-Objekt), sondern auch binäre Daten, wie double-Arrays, jpg-Images, etc. Insbesondere binäre Daten dürfen nur von geeigneten Spezialfunktionen weiter verarbeitet werden. Zur Implementierung solcher Funktionen sprechen sie uns gerne an.

Entfernen von Whitespace "sTrim"

Diese Funktion entfernt sämtlichen Whitespace am Anfang und Ende des Arguments, wie z.B. in

s_trimmed = sTrim(s);

Umwandlung in Groß-/Kleinschreibung "sUpper", "sLower"

Die Umwandlung eines Strings bzgl. Groß-/Kleinschreibung erfolgt mittels

s_uppercase = sUpper(s);
s_lowercase = sLower(s);

Vereinfachung "sSimplify" von Strings

Die Funktion sSimplify() ersetzt alle mehrfachen Aufkommen von White-Space (Leerzeichen, Tabulatoren, CR, LF, ...) durch ein einfaches Leerzeichen.

s_simple     = sSimplify(s);

Normierung "sNormalize" von Strings

Die Funktion sNormalize() entfernt zueinander passende Anführungszeichen "..."oder '...' am Anfang und Ende des Strings und ersetzt alle \-ESCAPE-Sequenzen durch ihren bezeichneten Code.

s_normalized = sNormalize(s); 

Suchen, Finden und Zerlegen

Suchen von Teilzeichenketten "sFind"

Die Suchfunktion sFind liefert den Index r oder eine Matrix mit Position und Länge der gefundenen Textteile des Musters p im String s zurück und kann wie folgt verwendet werden

r1 = sFind(s, {...});  //  Konfiguration des 'pattern' ist zwingend
r1 = sFind(s,p); // direkte Suche ab Stringbeginn
r2 = sFind(s,p,b); // direkte Suche ab Position b
// Optionales Konfigurationsobjekt für alle Varianten
rx = sFind(..., { pattern: <string>
, case: <bool>
, all: <bool>
, regex: <bool>
, subex: <bool>
});

Wird kein Muster gefunden, so liefert diese Funktion -1 zurück.

Eine Matrix mit den Suchergebnissen hat folgenden Aufbau:

rx=[s0c0s1c1sn1cn1]rx = \left[ {\begin{array}{cc} {{s_0}}&{{c_0}}\\ {{s_1}}&{{c_1}}\\ \vdots & \vdots \\ {{s_{n - 1}}}&{{c_{n - 1}}} \end{array}} \right]

Diese Matrix kann direkt zusammen der Zeilennummer des Einzelergebnisses an die Funktionen sCopy() oder sErase() übergeben werden.

Eine einzelnes Ergebnis kann mit der Funktion GetRow() oder durch direkte Angabe der Indizierung weiterverarbeitet werden:

part4    = sCopy(s, rx, 3);              // counting from zero
part4a = sCopy(s, rx[3,0], rx[3,1]); // equivalent
part4_sc = GetRow(rx, 3); // vector [s3, c3]
part4b = sCopy(s, part4_sc); // equivalent
EigenschaftWertBeschreibung
pattern<str>Konstantes Suchmuster, falls Parameter p nicht verwendet wird.
Ist etwas performanter für regex-Modi, da der Ausdruck nicht immer wieder neu übersetzt werden muss.
case<bool>Suche mit Berücksichtung von Groß- / Kleinschreibung, (def: false, case insensitiv)
all<bool>Liefert einen Vektor mit den Anfangspositionen und Längen der übereinstimmenden Textteile,
nicht in Verbindung mit subex
regex<bool>Interpretiert das Muster pattern oder p als Regular Expression, Ergebnis ist eine Matrix mit Position und Länge der gefundenen Ausdrücke/Teilausdrücke
subex<bool>Liefert Position und Länge der extrahierten Textteile in einer Ergebnismatrix,
setzt regex automatisch

Beispiele

//     0         1         2         3
// 0123456789012345678901234567890123456789
str = 'Hello world and hello my dear friends!';

p0 = sFind(str, "dog");
// => p0 := -1; // not found, independant of selected modes
// my test with (p0 < 0) ? ... : ...
// or isMatrix(p0) ? ... : ... for 'all'- or 'regex'-modes

p1 = sFind(str, "hello");
// => p1 := 0;

p2 = sFind(str, "hello", {case: true});
// => p2 := 16; // first one is now skipped

p3 = sFind(str, "hello", {all: true});
// => p3 := [ [ 0, 5]
// , [16, 5]];

p4 = sFind(str, "(and|dear)", { regex: true, all: true});
// => p4 := [ [12, 3]
// , [25, 4]];

p5 = sFind(str, 'dear\s+(\w+)', { subex: true });
// => p5 := [ [25, 12] // first row is complete match
// , [30, 7]]; // then (...) extractions follow

dear= sCopy(str, p5, 1);
// => dear:= 'friends';

// 0 1 2 3
// 0123456789012345678901234567890123456789
geo = 'lat: 51.234567, lon: 12.3456789';
p6 = sFind(geo, 'lat:\s*([0-9.+-]+)', {subex: true});
// => p6 := [ [ 0,14]
// , [ 5, 9]];
lat = dbl(sCopy(geo, p6, 1));
// => lat := 51.234567;

Ersetzen von Teilzeichenketten "sReplace"

Um (mehrere) Zeichenketten t_k innerhalb der Zeichenkette s durch die jeweils korrespondierenden Text von s_k zu ersetzen, kann folgendes verwendet werden

r = sReplace(s,t_1,s_1, ..., t_N,s_N);

Hierbei findet eine sequentielle Ersetzung in der Reihenfolge der Argumente statt, die Werte s_k werden implizit in eine Textdarstellung konvertiert. Für mehr Kontrolle bei der Konvertierung kann die Funktion sFormat() verwendet werden.

Beispiel:

template = 'alt: <alt>, lat: <lat>, lon: <lon>';
tx = sReplace(template, '<alt>', 140.4, '<lat>', 49.8765432, '<lon>', -3.14);
// tx := 'alt: 140.400000, lat: 49.876543, lon: -3.140000';

Suche nach Key-Value-Kombination "sGetKV"

Under Construction Diese Funktion ist in Vorbereitung.

Diese Funktion such in einem String (Text Block) nach einem Key-Value-Paar und gibt den Wert zurück.

v1 = sGetKV(s, k);
// Optionaler Konfigurationsblock
vx = sGetKV(..., { format: <enum>
, assign: <str>
, ending: <str>
, quotes: <bool>
, trim: <bool>
});
EigenschaftWertBeschreibung
format<enum>Mit dieser Eingeschaft wird das Format des Strings festgelegt. Mögliche Werte sind:
- json:
ini:
- csv:
assign<regex>Trennzeichen zwischen Key und Value, (def.: :)
ending<regex>Trennzeichen zwischen Key-Value-Einträgen, (def.: ,])
quotes<bool>Automatisches Entfernen von Anführungszeichen an Keys und Values. (def.: true)
trim<bool>Automatisches Entfernen von White-Space am Anfang und Ende eines Values  (def.: true)

Aufteilen von Zeichenketten "sSplit"

Um eine Zeichenkette an einem Zeichen ch aufzuteilen, kann die Funktion sSplit verwendet werden. Diese liefert eine zweispaltige Matrix aller Startpositionen und Längen der korrespondierenden Teilzeichenketten zurück

r1 = sSplit(s, ch);
// Optionaler Konfigurationsblock
rx = sSplit(..., { trim: <bool>
});
pos = rx[0, 0];
len = rx[0, 1];
EigenschaftWertBeschreibung
trim<bool>Entfernt White-Space am Anfang und Ende der Elemente

Anzahl der Zeilen innerhalb eines Strings "sLines"

Die Anzahl der Zeilen eines Strings s kann wie folgt ermittelt werden

lines = sLines(s);

Dabei werden alle Variante von Zeilenumbrüchen unterstützt (LF, CRLF, LFCR, CR).

Extraktion einer Zeile aus einem mehrzeiligen String "sLine"

Um die i-te Zeile aus einem String s zu extrahieren, bietet sich folgende Funktion an

lineI = sLine(s,i);
// Optionales Konfigurationsobjekt
lineX = sLine(..., { trim: <bool>
});
EigenschaftWertBeschreibung
trim<bool>Entfernt White-Space am Anfang und Ende der Zeile

Einlesen vollständiger Zeilen "sGetLine"

Die Funktion sGetLine() verbindet die einzelnen Werte aus dem String-Kanal s und speichert diese, bis eine vollständige Zeile ausgegeben werden kann. Diese wird aus dem Puffer entfernt und mit dem verbleibenden Rest wird die Akkumulation fortgesetzt.

Um aus einem Stream von Zeichen eine vollständige Zeile zu erhalten, kann folgendes verwendet werden

line1 = sGetLine(s);
// Optionales Konfigurationsobjekt
lineX = sGetLine(..., { trim: <bool>
, eoln: <str>
, timeout: <dbl>
});
EigenschaftWertBeschreibung
trim<bool>Die ausgegebene Zeile wird noch von Leerzeichen bereinigt
eoln<string>Definition des Zeilenabschlusses
timeout<dbl>Zeit in Sekunden nach dem letzte Fragment, bis ein Zeilenende eingefügt wird.