Suche Hilfe - unzulässige Zeichen bei Dateinamen ersetzen - mit "StringRegExp" für ANFÄNGER!

  • Werte Profis,

    ich quäle mich jetzt seit gut vier Wochen durch die "StringRegExp-Welt", muss aber schlichtweg feststellen, dass mir dass einfach zu hoch ist!

    Gutgemeinte Tipps und Links für "einfache Tutorials" helfen mir nicht wirklich weiter, ich habe Eure Reguläre Ausdrücke Sammlung und unzählige

    weitere Seiten gelesen - ich bin wahrscheinlich einfach zu b... dafür :rolleyes:

    Ich möchte in einem String folgende Zeichen ersetzen:

    ~ " # % & * : ; < > ? ! / \ { | } ^ ° ² ³ [ ]'

    um diese bei der Vergabe eines Dateinamens durch ein Leerzeichen zu ersetzen. (Bisher habe ich mittels Array jeden einzelnen Buchstaben des

    geplanten Dateinamens durchlaufen und ggf. ersetzt, wäre toll, wenn das einfacher/schneller ginge.)

    Vielen Dank - MfG Kilo

  • Ich verwende sowas um ungültige Zeichen in einem Dateinamen durch "_" zu ersetzen.
    Wo genau ich das gefunden habe ... keine Ahnung mehr :)

    Code
    $sNewName = StringRegExpReplace($sFilename, '[ \/:*?"<>|]', '_') ; replace invalid characters with underscore
  • Hallo water,

    vielen Dank, allerdings funktioniert das bei mir nicht ... !?

    $sFilename = "Teste \mich"

    $sNewName = StringRegExpReplace($sFilename, '[ \/:*?"<>|]', '_')

    ergibt bei mir: $sNewName = Teste_\mich

  • Deine konkrete Liste würde man so übersetzen: $sNewName = StringRegExpReplace($sFilename, '[~"#%&:;<>?!\/\\{|}^°²³[\]'']', ' ')

    Mit den Windows-Dateinamenkonventionen hat dies aber nicht unbedingt etwas zu tun, da z.B. die Raute in Dateinamen erlaubt ist.

    Wenn es stattdessen darum geht, alle nicht-erlaubten Zeichen zu entfernen, dann kann man auch folgende Windows-API-Funktion verwenden:

  • Deine konkrete Liste würde man so übersetzen: $sNewName = StringRegExpReplace($sFilename, '[~"#%&:;<>?!\/\\{|}^°²³[\]'']', ' ')

    Was aber zu Leerzeichen innerhalb des Dateinamens führt, daher finde ich die kompletten Zeichen entfernen besser, s. Win-API-Funktion!

    //EDIT habe gerade gesehen, dass ein / durch ein - ersetzt statt gelöscht wird?!

    @kilo, hast du bei https://regex101.com keinen Erfolg?! Ich bin auch nicht der große regex-crack, dafür nutze ich es zu selten, bzw. habe dank dieser Website auch überhaupt keine Veranlassung, mir "alles" bzgl. regex merken zu müssen...

    Wenn man erst einmal begriffen hat, wie reguläre Ausdrücke funktionieren, ist die Syntax absolut kein Problem mehr!

    Wissen ist wissen, wo es steht!!!

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (11. September 2022 um 15:17)

  • Vielen lieben Dank Euch allen! Kaum macht man es richtig, schon klappt es ... :)

    @AspirinJunki: Super, funktioniert prima

    @Andie: Der Link sieht sehr interessant aus, da werde ich künftig mal ein wenig "rumprobieren"

    Schönen Sonntag noch - MfG Kilo

  • Was aber zu Leerzeichen innerhalb des Dateinamens führt

    So war die Aufgabenstellung

    habe gerade gesehen, dass ein / durch ein - ersetzt statt gelöscht wird?!

    Hm - interessant. Du meinst die PathCleanupSpec() oder?

    Scheint eine Eigenart dieser Funktion zu sein.
    Ich kenne mich mit der aber nicht wirklich aus um zu entscheiden ob das gewollt oder ein Bug ist.

  • Ich kenne mich mit der aber nicht wirklich aus um zu entscheiden ob das gewollt oder ein Bug ist.

    Wenn man MSDN zu Rate zieht, dann ist das wohl gewollt. Das Flag wird jedenfalls entsprechend gesetzt:

  • Doku lesen hilft anscheinend - muss ich mir mal beherzigen.

    Dann wäre wieder ein Rätsel gelöst.

    Einen kleinen Klugschiss kann ich mir zum Sonntagabend aber nicht verkneifen: statt SetError(0, ...) könnte man eher ein SetExtended() nehmen... 8o

  • Doku lesen hilft anscheinend - muss ich mir mal beherzigen.

    Dann wäre wieder ein Rätsel gelöst.

    Hehe, "unbekannte" Funktion im Text doppelklicken und per Shortcut (ich benutze AutoIt um solche Funktionalität zu erreichen :P ) erhalte ich die google- und auch die MSDN-Abfrage.

    Genau das habe ich auch gemacht! Und auch das Flag hatte ich ausgewertet. Aber das ist doch gar nicht das Problem!

    The following are considered invalid characters in all names.

    \ / : * ? " < > |

    Na klasse, eine Liste mit "ungültigen" Zeichen! Soweit gut...

    In einer DOKUMENTATION(!) erwarte ich aber, dass mir zu jedem dieser Zeichen auch dargestellt wird, wie die Funktion diese behandelt?!

    Die anschließende Abfrage des Flags bringt mir zumindest überhaupt nichts, denn ich weiß nicht, welches Zeichen wie behandelt wird.

    Und DAS ist die essenzielle Frage in diesem Zusammenhang, denn niemand braucht eine Funktion die einen Dateinamen "validiert" wenn dieser anschließend in einem "unbekannten" Format weiterbearbeitet wird.

    Das Szenario:

    GUI mit Eingabe eines Dateinamens und anschließender "Prüfung" per PathCleanupSpec ergibt entweder "valid" oder "nicht valid" mit entsprechendem Rückgabestring. Und jetzt?

    Wenn ich nun dem User mitteilen möchte, dass er ein "falsches" Zeichen verwendet hat, wie finde ich das heraus bzw. was bringt mir/dem User die Info des Rückgabeflags?

    Und übrigens:

    Removes illegal characters from a file or directory name. Enforces the 8.3 filename format on drives that do not support long file names.

    Steht dort eindeutig "Removes" und kein Wort von "Replaces"?!

    Um beim Beispiel mit der GUI zu bleiben müsste ich eine Abfrage schreiben um das "invalide" Zeichen herauszufinden und ggf dem User mitzuteilen. Ich könnte auch den Rückgabestring dem User vorwerfen mit "Ungültige Zeichen gefunden, der Dateiname wurde in blablub geändert"....so weit waren wir aber per Regex schon mal....man kann sich diese "Funktion(alität)" von PathCleanupSpec also auch komplett sparen!

    Wobei es ein leichtes gewesen wäre zusammen mit dem Rückgabestring auch die von der Funktion geänderten/ersetzten Zeichen zurückzugeben...

    Werden allerdings Dateien von bspw. anderen Dateisystemen empfangen, dann ist es völlig egal wie die "ungültigen" Zeichen aus dem Dateinamen entfernt bzw. ersetzt werden, wichtig ist nur der valide Dateiname.

  • Removes illegal characters from a file or directory name.

    Der Funktionsname "PathCleanupSpec" ist ebenfalls sehr irreführend, denn es wird ein Verzeichnis- oder Dateiname erwartet, kein kompletter Pfad!

    Hier mal eine Funktion mit StringRegExpReplace:

    water - mit dem Pattern ist es etwas komplizierter...

    Einmal editiert, zuletzt von Bitnugger (14. September 2022 um 16:14) aus folgendem Grund: Tip von AspirinJunkie ($sPattern = '[\Q' & $sIllegalCharacters & '\E]') umgesetzt.

  • Eine kleine Anmerkung.

    Es gibt eine Ausnahme zu der Regel, dass kein Doppelpunkt im Dateinamen sein darf.

    Und zwar bei "Altenate Data Sets"

    Hier ein Script zum Test.

    Code
    $file = @DesktopDir & "\mytest.txt:alternateDS"
    MsgBox(262144, Default, "Filename:" & @CRLF & $file, 0)
    FileWrite($file, "This is an alternate dataset" & @CRLF & "This is line 2" & @CRLF & "This is line 3")
    ShellExecuteWait("notepad", $file)
    RunWait(@ComSpec & " /c " & "dir /R mytest.txt & pause & del mytest.txt", @DesktopDir, @SW_SHOW)
  • Und zwar bei "Altenate Data Sets"

    Das nennt sich "Alternate Data Streams (ADS)"

    NTFS und Alternate Data Streams (ADS)

    Habe dein Script ein wenig geändert...

    wenn es kompiliert (*.exe) gestartet wird, sieht die Ausgabe so aus: