Sonderzeichen in Dateinamen aufspüren

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
jann.stueven
Beiträge: 4
Registriert: Do 26. Jan 2017, 20:11

Sonderzeichen in Dateinamen aufspüren

Beitrag von jann.stueven »

Hallo,

Ich habe ein Programm geschrieben welches alle Dateien in einem Verzeichnis nach einem Muster umbenennt. Weil das nachfolgende Programm Probleme mit ÜÖÄ habe ich eine Funktion integriert die die gängigsten Sonderzeichen löscht oder ändert (ö in oe).
Diese Funktion funktioniert mir Windowsdatenamen wunderbar aber mit Dateien von einen MAC nicht, da diese anders codiert sind.

Funktion umlaute(dateiname: String )

if Pos('ü', Dateiname ) > 0 then
begin
ersetze_durch('ue'); (nur Symbolhaft)
end;
.....

da im MAC das ü aus 2 Zeichen besteht, aus dem u + ( unicode U+00A8 ¨ Utf8 c2 a8) kann es nicht gefunden werden.

Wie kann man diese Zeichen in einem String, Widestring oder sonstwas finden?
Ich habe den Dateinamen schon mit verschiedensten Utf82... oder Univode2... funktionen zu verändern versucht aber finden kann ich die immer noch nicht.

Hat jemand eine Idee?

Natürlich wäre es einfacher auf Umlaute zu verzichten aber diese werden in einem fremden System automatisch aus den Klar_Nachnamen von Personen in einer Datenbank gebildet. Und da möchte der Herr Müller nicht mit ue geschrieben werden.

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von wp_xyz »

Eigentlich arbeitet Lazarus direkt mit UTF8. Verwende statt pos die Funktion UTF8Pos aus der Unit LazUTF8. Und zum Austauschen der Substrings nimm UTF8StringReplace statt StringReplace. Welche Lazarus-Version hast du? Und wie hast du die Dateinamen erhalten? Unter Windows musst du evtl noch eine geeignete Konvertierung nach UTF8 vornehmen (wahrscheinlich WinCPToUTF8 oder UTF16ToUTF8, beides auch in LazUTF8).

jann.stueven
Beiträge: 4
Registriert: Do 26. Jan 2017, 20:11

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von jann.stueven »

Danke erstmal für die Tips.
meine Version ist 1.6.x FPC 3.0.0 Rev 51630
Die Funktion UTF8Pos findet auch nichts, nur die Windowsumlaute und die gingen auch vorher.
Der Umlaut wird immer als ü o.ä. angezeigt, nur in der CMD-Box zeigt es z.B. Mu''ller an. danach kann ich nicht suchen weil ich die Eingabeform nicht kenne. Früher habe ich mal mit asc(123) gearbeitet für die ASCII Sonderzeichen aber da gingen die nur bis 255.g

Die Dateien erhalte ich in Zip-Dateien via Mail, Cloud-Ablage oder CD, so um die 2000 Dateien davon ca 10% mit Umlauten, zuviel um manuell umzubenennen.
Die Dateinamen verarbeitete ich zzt. in einer Stringlist

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von wp_xyz »

Ich weiß immer noch nicht was du machst. Ob du die Dateien per CD oder zip oder Mail erhältst, ist egal, wichtig ist, mit welchen Befehlen du den Dateinamen erhältst. Wenn das irgendwelche Systemaufrufe sind, die keine UTF8 zurückgeben, musst du evtl. ein Konvertierungsfunktion aufrufen, falls fpc3 das nicht erkennt. Ansonsten habe ich aber mit Windows und Linux überhaupt kein Problem mit folgendem Code (Achtung: es muss das Package LazUtils als Anforderung ins Projekt aufgenommen werden, sonst wird LazUTF8 nicht gefunden):

Code: Alles auswählen

program project2;
 
{$mode objfpc}{$H+}
 
uses
  SysUtils, LazUTF8;
 
var
  Info: TSearchRec;
  s: String;
 
begin
  if FindFirst('*', faAnyFile and faDirectory, Info) = 0 then
  begin
    repeat
      with Info do
      begin
        If (Attr and faDirectory) = faDirectory then  s := 'Dir: ' else s := '';
        s := s + Name + ' Size: ' + IntToStr(Size);
        if Utf8Pos('ä', Name) <> 0 then s := s + ' ---> UMLAUT ä';
        if Utf8Pos('ö', Name) <> 0 then s := s + ' ---> UMLAUT ö';
        if Utf8Pos('ü', Name) <> 0 then s := s + ' ---> UMLAUT ü';
        WriteLn(s);
      end;
    until FindNext(info)<>0;
  end;
  FindClose(Info);
  ReadLn;
end.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von Michl »

Noch als Ergänzung. Es könnte sein, daß ein ä, ö oder ü nicht per C3A4 (LATIN SMALL LETTER A WITH DIAERESIS), C3B6 (LATIN SMALL LETTER O WITH DIAERESIS) oder C3BC (LATIN SMALL LETTER U WITH DIAERESIS) sondern als a, o oder u mit Combining Diacritical Marks dargestellt werden. Ich habe keinen MAC um das zu testen, im Wiki gibt es aber einen Hinweis darauf: http://wiki.lazarus.freepascal.org/LCL_Unicode_Support/de#Mac_OS_X

Ansonsten könnte die Normalisierung helfen, evtl. mit theos UTF8Proc Port?!: http://www.theo.ch/lazarus/utf8proc_pas.zip

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

jann.stueven
Beiträge: 4
Registriert: Do 26. Jan 2017, 20:11

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von jann.stueven »

LazUtf8 wird gefunden, kein Problem.

Ich habe den vorgeschlagenen Code mal in mein Projekt integriert mit gleichem Ergebnis. Das MAC ü wird nicht gefunden da es wie Eingangs und durch 'Michl' erwähnt nicht mit dem bei Pos (Utf8Pos) eingegeben ü übereinstimmt.

Temp : RawByteString;

das von mir benutze FindAllFiles() liefert im RawByteString das gleiche wie info.Name.

MAC ü ='u#204#136' Windows ü = '#195#188'
MAC ö ='o#204#136' (LATIN SMALL LETTER O WITH DIAERESIS)

Ich muss also #204#136 finden, nur Pos('#204#136',Temp) geht doch nicht.

Noch mal die Eingangsfrage: "Wie gebe ich diese Zeichen (DIAERESIS) bei Pos(), Utf8pos(), whatever ein damit ich es entfernen kann.

wp_xyz
Beiträge: 4889
Registriert: Fr 8. Apr 2011, 09:01

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von wp_xyz »

Wieso RawByteString? Das macht doch nur unnötige Probleme - die allermeisten Programme gehen mit String. Und wenn du dann Utf8Pos('ö', ...) bzw pos(#204#136,..) (ohne die Hochkommas!) verwendest, dann muss es gehen

jann.stueven
Beiträge: 4
Registriert: Do 26. Jan 2017, 20:11

Re: Sonderzeichen in Dateinamen aufspüren

Beitrag von jann.stueven »

wp_xyz hat geschrieben:Und wenn du dann Utf8Pos('ö', ...) bzw pos(#204#136,..) (ohne die Hochkommas!) verwendest, dann muss es gehen

Stmmt, damit geht es, genau danach hatte ich gefragt. Ich wusste nicht dass das so geht.

RawByteString lieferte mir nur die entsprechenden Nummern '#204#136' etc, bei String wurde immer nur ein ü gezeigt z.B. wenn man die Maus bei einen Haltepunkt über die Variable hält. Beim normalen Programmablauf geht es mit Strings und Pos(#204....) auch ohne UTF8 Funktionen

Danke für die Hilfe, Lösung ist da und es läuft bereits.

Antworten