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 Stringss_connected = s1 + s2;
tippstr(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 FunktionsFormat(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"
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>
Datentyp Ausgabe 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) ZiffernA
-F
o <uint>
Ganzzahl ohne Vorzeichen, Basis 8 f <dbl>
Fließkommazahl ohne 10er-Exponent
Beispiel: 1234.5678g <dbl>
Fließkommazahl in optimierter Darstellung
wie f oder e je nach Größenordnung der Zahl.
Beispiele: 1234.45678, 1.2345e9, 1.2345e-12e <dbl>
Fließkommazahl mit 10er-Exponent
Beispiel: 1.2345678e3s <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'});
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:
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
Eigenschaft | Wert | Beschreibung |
---|---|---|
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"
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>
});
Eigenschaft | Wert | Beschreibung |
---|---|---|
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];
Eigenschaft | Wert | Beschreibung |
---|---|---|
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>
});
Eigenschaft | Wert | Beschreibung |
---|---|---|
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>
});
Eigenschaft | Wert | Beschreibung |
---|---|---|
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. |