Dateinamen generieren, der Ausdruck mit Wildcards entspricht
-
Was du da beschreibst, ist kein regulärer Ausdruck. Was willst du wirklich?
-
Sind Wildcards keine Untergruppe regulaerer Ausdruecke? Na gut. Es bringt mich bei meinem Problem kein bisschen voran, aber ich nehme es zur Kenntnis.
Und sonst gilt: Wenn du mir helfen koenntest, haettest du es hoffentlich getan. Profiliere dich bitte an anderer Stelle.
-
Junge, wenn man mit komplexen Problemen kommt, muss man sich schon genau überlegen, was man will und das dann auch so beschreiben. Nein, Wildcards sind keine regulären Ausdrücke, und selbst wenn sie eine Untermenge selbiger wären, wäre das eine wichtige Information, weil das Problem dadurch einfacher würde. Wenn du nur Sterne ersetzen willst, solltest du auch das ausdrücklich sagen.
Mit regulären Ausdrücken halte ich das Vorhaben in endlicher Zeit für undurchführbar. Mit Wildcards läuft es im Wesentlichen darauf hinaus, das hinterste Wildcard-Zeichen zu finden, zu sehen, welchen Teil im vorhergehenden String es matcht und diesen im neuen String durch den nächsthöheren String zu ersetzen. Wenn ? und [] gewollt ist, läuft man damit in Probleme, wenn zwei aufeinanderfolgende Strings schon enthalten sind und keiner dazwischen passt, wenn es nur um Sterne geht, stellt sich das Problem nicht. Auch stellt sich ggf. die Frage, welches Globbing du eigentlich haben willst.
Nächstes mal komm mit einer vernünftigen Problembeschreibung. Dann habe ich auch einen freundlicheren Ton drauf.
-
seldon schrieb:
Junge, wenn man mit komplexen Problemen kommt, muss man sich schon genau überlegen, was man will und das dann auch so beschreiben. Nein, Wildcards sind keine regulären Ausdrücke, und selbst wenn sie eine Untermenge selbiger wären, wäre das eine wichtige Information, weil das Problem dadurch einfacher würde. Wenn du nur Sterne ersetzen willst, solltest du auch das ausdrücklich sagen.
Den Begriff "regulärer Ausdruck" hast Du ins Spiel gebracht. Bei "Unix Wildcards" im Zusammenhang mit Dateinamen sollte eigentlich relativ klar sein, dass Globs gemeint sind, wie sie eine (Standard-)Shell expandiert.
@TE:
Ich würde das Muster zeichenweise durchgehen und jedes nicht-Wildcard in einen neuen String kopieren. Beim ersten Wildcard hängst Du an das Ergebnis eine Zeichenkette an, die aus den lexikografisch niedrigsten Zeichen besteht, die der Dateiname enthalten darf (z.B. "0"). Dann das gleiche mit dem Rest vom Dateinamen, wobei Du da die Wildcards auch überlesen kannst. Dann prüfst Du, ob der generierte Name schon in der Liste vorkommt und ob er an der korrekten Position (oben) landen würde. Wenn er nicht oben landen würde, wiederholen mit "00". Wenn es dann Duplikate gibt, hochzählen, z.B. "01"...Ganz grob...

-
Muss der generierte Dateiname irgendetwas mit dem Originalnamen zu tun haben? Wenn nicht, ist es zumindest theoretisch relativ einfach, aus einem gegebenen regulären Ausdruck dazu passende Strings zu generieren. Es sollte auch möglich sein, Strings zu generieren, die alphabetisch nach einem anderen kommen. Ich weiß aber nicht, ob das auch besonders hübsch und passend geht (die einfachste Möglichkeit wäre, beim ersten * den String passend zu füllen und dann einfach irgendwas passendes dranzuhängen).
-
LordJaxom schrieb:
seldon schrieb:
[...]regulären Ausdrücke[...]
Den Begriff "regulärer Ausdruck" hast Du ins Spiel gebracht.
Nein, der stammt schon von mir. Ich habe meine Posts aber editiert, da sonst vielleicht nichts als hochnaesiges Geschwaetz hier ankommt.
Im weitesten Sinne scheint ein Wildcard-Ausdruck ein regulaerer Ausdruck zu sein - zumindest entnehme ich das der groben Definition bei Wikipedia. Nutzen moechte ich nicht nur Sterne, sondern das Wildcard-Spektrum (*?[]), inklusive Escape-Zeichen.LordJaxom schrieb:
Ich würde das Muster zeichenweise durchgehen und jedes nicht-Wildcard in einen neuen String kopieren. Beim ersten Wildcard hängst Du an das Ergebnis eine Zeichenkette an, die aus den lexikografisch niedrigsten Zeichen besteht, die der Dateiname enthalten darf (z.B. "0"). Dann das gleiche mit dem Rest vom Dateinamen, wobei Du da die Wildcards auch überlesen kannst. Dann prüfst Du, ob der generierte Name schon in der Liste vorkommt und ob er an der korrekten Position (oben) landen würde. Wenn er nicht oben landen würde, wiederholen mit "00". Wenn es dann Duplikate gibt, hochzählen, z.B. "01"...
Das klingt nach einem Anfang. Ich zerlege meinen String an allen Wildcards und gehe dann die Wildcard-Bruchstuecke in noch unbekannter Reihenfolge durch um Sachen einzufuegen.
Vielleicht muss ich noch ein paar Naechte drueber schlafen, damit mir eine Idee kommt, wie ich das ganze umgehen kann. Bisher hat das Schlafen leider nichts gebracht.ipsec schrieb:
Muss der generierte Dateiname irgendetwas mit dem Originalnamen zu tun haben?
Es waere ganz nett, wenn die Dateiendung erhalten bliebe. Aber eventuell kann ich garantieren, dass in den Endungen keine Wildcards verwendet werden. Ansonsten darf der Name beliebig geaendert werden.
ipsec schrieb:
Ich weiß aber nicht, ob das auch besonders hübsch und passend geht (die einfachste Möglichkeit wäre, beim ersten * den String passend zu füllen und dann einfach irgendwas passendes dranzuhängen).
Funktionalitaet waere erstmal das Wichtigste. Dass das ganze unschoen wird, befuerchte ich schon laenger.
-
Es geht sogar noch einfacher. Wir nehmen an, es soll ein Dateiname generiert werden, der alphabetisch nach dem Dateinamen A kommt und auf das Muster passt. Wir wissen aber, dass auch A auf das Muster passt. Also müssen wir uns nur das letzte Wildcard im Muster suchen und basierend auf A an der entsprechnden Stelle (die ja somit einfach zu ermitteln ist, da dahinter kein Wildcard kommt) entweder ein passendes Zeichen einfügen oder ein Zeichen hochzählen.
Beispiel (Endungen mal ausgelassen):
Muster: a*b*c A: a123b345c Neu: a123b345dc Oder: a123b346cWenn es * oder [] ist, können wir nur hochzählen.
Jetzt kommt noch der Spezialfall, dass es diesen Namen schon gibt. Dann müssen wir eine andere Alternative wählen. Wenn wir ein Zeichen einfügen statt hochzuzählen, sollte es auch im allgemeinen nicht möglich sein, dazwischen noch etwas einzufügen. Deswegen wäre es vielleicht abhängig vom Problem klüger, nicht direkt das nächste Zeichen zu nehmen, mit dem Risiko, dass der generierte Name dann alphabetisch nicht direkt hinter dem gewünschten kommt.
Wenn ein beliebiger Name sein soll: für * irgendetwas einfügen (oder leer lassen), für ? irgendein Zeichen nehmen, bei [] irgendeins aus der Range, alle anderen Zeichen übernehmen, so dass der Name noch nicht vorkommt.
Ist natürlich nicht hübsch, aber leicht umsetzbar.
-
Leicht umsetzbar also...ich vermute fast, dass du das nicht behaupten wuerdest, wenn du die Umsetzung tatsaechlich mal angegangen waerst.

Mein Vorgehen ist bisher folgendes:
1. Umwandlung des Wildcard-Ausdrucks in einen regulaeren Ausdruck mit Capture-Faehigkeit (nur zur Verdeutlichung: a?b*.txt -> a(.)b(.*?)\.txt)
2. der regulaere Ausdruck arbeitet auf den Dateinamen und gibt mir somit Zugriff auf die variablen Anteile der NamenWildcard-Ausdruck: a?b* A: a3b34a B: a4b34a Ausgabe: ? -> "3" bzw. "4" * -> "34a" bzw. "34a"Vielleicht ist schon der Ansatz Bloedsinn, aber das sieht meiner Meinung nach schon ganz gut aus. Weiter komme ich allerdings momentan nicht, vielleicht hat jemand eine Anregung.
-
Ok, ich hab mal kurz was zusammengeschrieben.
./prog name patternerzeugt einen aufpatternpassenden neuen Namen, der alphabetisch nachnamekommt, unter der Voraussetzung, dass auchnameaufpatternpasst.
Fehlerbehandlung, Tests, Verhalten, wenn Name schon existiert, usw. sind nicht drin, außerdem werden nur * und ? unterstützt. Aber es verdeutlicht vielleicht die Idee.#include <iostream> #include <string> int main(int argc, char *argv[]) { using namespace std; if(argc != 3) return 1; string name = argv[1]; string pattern = argv[2]; size_t index = pattern.find_last_of("*?"); if(index == string::npos) cerr << "no wildcards in pattern\n"; else { index = pattern.size() - index; ++name[name.size()-index]; cout << name << '\n'; } }Beispiele:
./prog foobar '*' foobas ./prog fooABCbarDEFGbazHxy 'foo*bar*baz?xy' fooABCbarDEFGbazIxy ./prog FOO123 '*123' FOP123
-
Danke fuer den Code, auch wenn der Gedanke schon klar war ;). Mein Problem ist, dass ich bisher keine Idee habe, wie verfahren werden soll, wenn kein Name gefunden wird. Das heisst, dass ich soviele Faelle wie moeglich abdecken moechte.
Vielleicht gehe ich doch erstmal eine ganz einfache Implementierung an und erweitere dann, wo moeglich.