Text Transformation Language
Verfasst: 22.09.2012, 14:43
Ich brauche auf der Arbeit oft Scripts und Tools für Textersetzungen und Umbenennung von Dateien. Meist reicht dafür ein Regex.Replace nicht aus und so habe ich angefangen eine kleine Text Transformation Language zu basteln, mit der ich die meisten Aufgabenstellungen erschlagen kann.
1. Aufbau:
Um eine Text-Transformation durchzuführen wird ein Ausdruck verwendet der aus 1-11 Bereichen besteht. Bereiche werden durch eine Raute (#) getrennt:
Der erste Bereich ist der Ergebnisbereich, die anderen Bereiche sind Hilfsbereiche, die mit einer ID von 0-9 in allen Bereichen referenziert werden können. Der erste Bereich ist nicht referenzierbar. Das Resultat der Transformation befindet sich am Ende im Ergebnisbereich. Man kann sich dies in etwa wie einen Formatstring bei printf vorstellen, wobei weitere Bereiche dann Text-Parameter sind die im Formatstring eingefügt werden können. Allerdings sind alle Bereiche sozusagen Formatstrings. So kann beispielsweise der 2. Bereich ebenfalls andere Bereiche referenzieren. Zu beachten ist dabei, dass sich 2 Bereiche nicht gegenseitig referenzieren dürfen und das es keine Ring-Referenzierung gibt (z.B. Bereich 3 -> Bereich 4 -> Bereich 5 -> Bereich 3).
Jeder Bereich kann Text, Operatoren, Referenzen auf Bereiche und Variablen enthalten (siehe weiter unten).
2. Referenzierung von Bereichen:
Ein Bereich wird mit einem Dollarzeichen gefolgt von der Bereichs-ID referenziert. Z.B. $0, $1, usw. Da die ID immer einstellig ist referenziert $9 den letztmöglichen Bereich. Ist ein referenzierter Bereich nicht vorhanden, so wird dieser als leerer String interpretiert.
Beispiel:
Referenziert ein Bereich andere Bereich, so werden zunächst diese referenzierten Bereiche transformiert und anschließend eingefügt. Danach wird der Bereich selbst transformiert.
3. Operatoren:
Beispiele:
4. Variablen
In der Regel möchte man nicht mit festen Strings arbeiten, da man dann keine Text-Transformation bräuchte. Daher können Variablen referenziert werden. Diese können Strings oder Zahlenwerte beinhalten. Sofern es sich um Zahlenwerte handelt können diese auch als Parameter für bestimmte Operatoren (z.B. Index, Substring, Repeat, usw verwendet werden).
Referenzen auf Variablen werden mit einem @ begonnen und beendet: @myvar@. In Parametern für Operatoren reicht der Variablenname ohne das @-Zeichen aus.
Ein Programm welches die TT-Sprache nutzt muss dem Interpreter/Transformator die Variablen mitgeben. Die Variablennamen selbst beinhalten nicht das @-Zeichen. Dies ist nur bei der Referenzierung nötig.
Beispiel:
Ich würde mich über Anmerkungen, Kritik und Ideen freuen.
Das Ziel ist beispielsweise ein Kommandozeilen-Tool ala awk, mit dem man auf einfache Weise Dateien umbenennen kann oder in Texten sehr einfach Inhalte ändern oder formatiert einfügen kann. Ich könnte mir auch vorstellen, dass man damit Dateininhalte formatiert anzeigen oder ausgeben lassen kann ohne jedesmal ein Programm zu schreiben.
Man könnte es aber auch als Regex-Alternative in Bibliotheken zur Verfügung stellen um bestimmte Textersetzungen zu ermöglichen.
Wer Lust hat kann ja rausfinden was der Ausdruck in meiner Signatur ergibt. ;)
1. Aufbau:
Um eine Text-Transformation durchzuführen wird ein Ausdruck verwendet der aus 1-11 Bereichen besteht. Bereiche werden durch eine Raute (#) getrennt:
Code: Alles auswählen
Bereich1#Bereich2#...#Bereich11
Jeder Bereich kann Text, Operatoren, Referenzen auf Bereiche und Variablen enthalten (siehe weiter unten).
2. Referenzierung von Bereichen:
Ein Bereich wird mit einem Dollarzeichen gefolgt von der Bereichs-ID referenziert. Z.B. $0, $1, usw. Da die ID immer einstellig ist referenziert $9 den letztmöglichen Bereich. Ist ein referenzierter Bereich nicht vorhanden, so wird dieser als leerer String interpretiert.
Beispiel:
Code: Alles auswählen
$0$1$2$9#Hallo# #Welt
// Ergebnis: "Hallo Welt"
3. Operatoren:
Code: Alles auswählen
> UpperCase (Wandelt den vorangegangen String in Großbuchstaben um)
< LowerCase (Wandelt den vorangegangen String in Kleinbuchstaben um)
~ Reverse (Dreht die Reihenfolge der Zeichen um)
+ RepeatChar (Wiederholt das letzte Zeichen)
- RemoveChar (Entfernt das letzte Zeichen)
() Block (Markiert einen Block auf den sich der nachfolgende Operator bezieht, ansonsten wirken die meisten Operatoren auf den gesamten vorangegangen Text)
[i] Index (Liefert das i-te Zeichen)
[i,l] Substring (Liefert den Teilstring vom Index i an mit der Länge l)
Ist i negativ so wird vom Ende ausgegangen: RealIndex = String.Length + i
Ist l negativ so wird der Ergebnisstring umgedreht
Fehlt l aber das Komma ist vorhanden, so handelt es sich um den Substring bis zum Ende (abc[1,] liefert "bc")
{n} Repeat (Wiederholt den Text n mal)
{c,n} RepeatRange (Wiederholt die letzten c Zeichen, n mal)
{"r"} Regex (Wendet den regulären Ausdruck r an, das Match wird zurückgegeben)
\c Escape (Liefert das Zeichen c ohne es zu interpretieren, z.B. \< ergibt das Zeichen '<')
Code: Alles auswählen
Eingabe: test>
Ergebnis: TEST
Eingabe: foo[1]>
Ergebnis: O
Eingabe: Test123{"[0-9]+"}~
Ergebnis: 321
Eingabe: Go{1,4}gle
Ergebnis: Gooooogle
Eingabe: C\++
Ergebnis: C++
Eingabe: $0($1){2}#once#twice
Ergebnis: oncetwicetwice
4. Variablen
In der Regel möchte man nicht mit festen Strings arbeiten, da man dann keine Text-Transformation bräuchte. Daher können Variablen referenziert werden. Diese können Strings oder Zahlenwerte beinhalten. Sofern es sich um Zahlenwerte handelt können diese auch als Parameter für bestimmte Operatoren (z.B. Index, Substring, Repeat, usw verwendet werden).
Referenzen auf Variablen werden mit einem @ begonnen und beendet: @myvar@. In Parametern für Operatoren reicht der Variablenname ohne das @-Zeichen aus.
Ein Programm welches die TT-Sprache nutzt muss dem Interpreter/Transformator die Variablen mitgeben. Die Variablennamen selbst beinhalten nicht das @-Zeichen. Dies ist nur bei der Referenzierung nötig.
Beispiel:
Code: Alles auswählen
myvar1 = "foo"
myvar2 = 2
Eingabe: $0[myvar2,]#@myvar1@$1@myvar1@z#bar
Ergebnis: barfooz
Ich würde mich über Anmerkungen, Kritik und Ideen freuen.
Das Ziel ist beispielsweise ein Kommandozeilen-Tool ala awk, mit dem man auf einfache Weise Dateien umbenennen kann oder in Texten sehr einfach Inhalte ändern oder formatiert einfügen kann. Ich könnte mir auch vorstellen, dass man damit Dateininhalte formatiert anzeigen oder ausgeben lassen kann ohne jedesmal ein Programm zu schreiben.
Man könnte es aber auch als Regex-Alternative in Bibliotheken zur Verfügung stellen um bestimmte Textersetzungen zu ermöglichen.
Wer Lust hat kann ja rausfinden was der Ausdruck in meiner Signatur ergibt. ;)