PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit Perl deutsche Umlaute ersetzen



craano
19-02-2007, 00:06
Hallo,

ich versuche gerade mit einem kleinen Perscript in einer Textdatei alle Umlaute zu ersetzen. Doch leider ignoriert das Pattern Matching sämtliche Umlaute.
Beispiel:

$Text =~ s/ä/ae/g;
$Text =~ s/ö/oe/g;
$Text =~ s/ü/üe/g;
$Text =~ s/Ä/Ae/g;
$Text =~ s/Ö/Oe/g;
$Text =~ s/Ü/Ue/g;
$Text =~ s/ß/sz/g;
Wenn ich andere Zeichen als Muster eingebe, dann funktioniert die Substitution problemlos.

Grüße.
craano.

craano
19-02-2007, 10:54
Edit: Unsinn Gepostet.

craano
19-02-2007, 11:17
Ich poste hier mal den gesamten Code - Abschnitt.
Ich denke mittlerweile, dass die Daten schon beim einlesen falsch interpretiert werden.

my $i = 0;
my $Text;

find(\&wanted, '/home/craano/Desktop/Musik');
sub wanted {


if (m/mp3/ || m/MP3/){
$i++;
my $mp3 = MP3::Tag->new($_);
$mp3->config("autoinfo","ID3v1","ID3v2");
my ($title, $track, $artist, $album, $comment, $year, $genre) = $mp3->autoinfo();
$Text = $i." ; ".$artist." ; ".$album." ; ".$track." ; ".$title." ; ".$year." \n";

$Text =~ s/ä/ae/g;
$Text =~ s/ö/oe/g;
$Text =~ s/ü/ue/g;
$Text =~ s/Ä/Ae/g;
$Text =~ s/Ö/Oe/g;
$Text =~ s/Ü/Ue/g;
$Text =~ s/ß/sz/g;

print $Text;
}
}Die Ausgabe von print ist verunstaltet. Jeder Umlaut wird so dargestellt. " � ". Eine weitere sinnvolle Verwendung von $Text ist so leider nicht möglich.

Ich hoffe jemand von Euch hat noch eine Idee.

Wenn ich die Ausgabe in eine Datei pipe, dann kann ein Editor (gedit) die Sonderzeichen darstellen! Ein less "datei" zeigt mir die Sonderzeichen nicht an, sondern substituiert diese. Ein "ö" wird zu <F6> und ein "ä" wird als <E4> angezeigt.

Was bedeutet das. Wie bekomme ich die Umlaute auf der Shell richtig angezeigt, dass ist nötig, weil ich aus diesen Informationen Dateinamen generieren will, das ist ohne richtige Sonderzeichen wenig sinnvoll.

btw: Wenn ich direkt ein

print "äöü";
ausgeben lasse, dann werden die Zeichen auch in der Shell richtig dargestellt.

Grüße.
craano.

undefined
19-02-2007, 13:47
Ist sehr wahrscheinlich ein Editor Zeichensatz Problem.
* In welchen Format wird gespeichert?
* Ist das Format Identisch mit der meiner Umgebung. export -p | grep LC
* Wie kann ich Umwandeln iconv --help

craano
22-02-2007, 18:45
Habe mittlerweile die Lösung.

use utf8;
utf8::encode($_);
bzw
utf8::decode($_);


lassen die Umlaute unverstümmelt erscheinen.

Grüße.
craano.

undefined
22-02-2007, 20:38
Dann fängt aber das Drama an.
Wann ist es ein utf8 und wann nicht ;)
Ein Work Arround wäre.


my $str;
my $check = utf8::encode( utf8::decode($_) );
if ( $check == $_ )
$str = $_;
else
$str = utf8::encode( $_ );

Es ist Besser du versuchst von Anfang an einen Einheitlichen Zeichensatz zu haben. Sonst wirst du immer wieder das Problem haben.

craano
23-02-2007, 14:35
Ok, da hast natürlich recht lieber gleich sauber arbeiten.
Ich beschreibe das Problem noch einmal genau, alle Umformatierungen wieder entfernt, weil nicht zufriedenstelllend.

Mit diesem script erzeuge ich eine csv Datei:

#!/usr/bin/perl
#
#
#
#
use File::Copy;
use MP3::Tag;
use File::Find;
use utf8;
use Cwd;
my $dir;


my $i = 0;
my $Text;

##Kopfzeile
print "Nr. ; Artist ; Album ; Track ; Title ; Year ; Name Of File ; Path To File \n \n";


find(\&wanted, '/home/kai/Desktop/Musik');

sub wanted {


if (m/mp3/ || m/MP3/){
$i++; $dir = getcwd;
my $mp3 = MP3::Tag->new($_);
$mp3->config("autoinfo","ID3v2");
my ($title, $track, $artist, $album, $comment, $year, $genre) = $mp3->autoinfo();


$Text = $i." ; ".$artist." ; ".$album." ; ".$track." ; ".$title." ; ".$year. ";" . $_ . ";" . $dir . " \n";


print $Text;
}
}
print "\n;;";print $i;print " Dateien gelistet. \n";
my $CTIME_String = localtime(time);print ";;List generated at: $CTIME_String";Auf der Konsole sieht die Ausgabe für eine betroffenen Zeile dann zB so aus:

1 ; Die drei ??? ; Die drei ??? 107 und der Schatz der M�nche ; 01 ; 01 - Das geheimnisvolle K�stchen ; ;01 - Das geheimnisvolle Kästchen.mp3;/home/kai/Desktop/MusikWenn ich diese Datei mit der Tabellenkalkulation von Open Office öffne, ist die Ausgabe genauso.

Diese Datein werden von einem HTML inkludierten Perl Script gelesen und in eine HTML Tabelle eingefügt. Die Webseite wird im Browser /Firefox / Konqueror) korrekt dargestellt. Auch http://validator.w3.org/ hat nichts zu meckern ist valid HTML 4.01 Transitional und die Umlaute stimmen.

Wenn ich die Datei mit einem Texteditor (gedit / vim) öffne, dann ist die Dartstellung auch korrekt.

Ich verstehe jetzt nicht genau, was ich mit

$Text = $i." ; ".$artist." ; ".$album." ; ".$track." ; ".$title." ; ".$year. ";" . $_ . ";" . $dir . " \n";anstellen soll, um immer eine korrekte Darstellung zu haben.

Am besten wäre es eine Lösung zu finden, die schon bei der Datenerfassung die Buchstaben in ein korrektes Format konvertiert, welches immer richtig ausgegeben wird, da ich das ganze später auf eine Datenbank basierte Lösung umstellen will. (Noch nicht entschieden welchen Datenbank ich benutzen werde MySQL oder weil handy und für die Aufgabe gewachsen vielleicht SQLite). Es wäre also wünschsenswert die Daten von vornherein korrekt in die DB einzutragen und nicht erst beim SELECTen zu konvertiern.

Weder ein:
utf8::encode($Text);
noch ein:
utf8::decode($Text);
noch ein:
utf8::encode($Text);
utf8::decode($Text);
bringt einen zufriedenstellenden Erfolg. Die Ausgabe verändert sich zwar, doch werden die kryptischen Zeichen nur durch andere ersetzt:


Kästchen

Muss ich den String vielleicht zeichenweise abarbeiten, weil er nicht einheitlich formatiert ist?

So ganz habe ich Deinen Code nicht verstanden. Was soll ich denn mit dem String machen?

Grüße.
craano.

undefined
23-02-2007, 16:45
Und genau da sind wir bei dem Drama, als ich vor zwei Jahren auf UTF-8 umgestellt habe bin ich dabei fast verzweifelt.
Die Lösung deines Problem ist iconv.
mal ein Beispiel wie ich fremde Datenbank Exporte erst Konvertiere bevor ich sie bei mir über die Console einspielen kann.


for i in `ls *.sql`; do
if [ -e $i ] ; then
echo "Konvertiere $i nach UTF-8"
iconv -f ISO-8859-1 -t UTF-8 $i > utf8.$i
fi
done


Du kannst zwar im Dokument Konvertieren, aber du siehst ja selbst das es nie Gleich angezeigt wird.
Hier Spielen z.B. bei der WWW Entwicklung auch noch die header() Informationen eine große Rolle.
Ist deine Anwendung fürs das Web oder nur eine Konsolen Programm?


Kästchen
das weist ganz klar auf eine Header Informations Problem hin.

craano
23-02-2007, 22:01
Die Anwendung ist zur Zeit in erster Linie für das Web. Ab und an bearbeite ich die Ausgabe Dateien auch mit der Open Office Tabellenkalkulation. Weder im Browser, noch in Open Office treten ja diese Zeichen auf. Die Umlaute werden nur in der Konsole (teilweise) verstümmelt dargestellt.

Ich mache mir nur ein wenig Sorgen, wenn ich die Daten in eine Datenbank und nicht in eine Datei schreibe, dass dann die Umlaute nach dem SELECT immer noch im Browser korrekt angezeigt werden.

Mir wäre eine Lösung am liebsten, bei der die Datensätze immer so konvertiert werden, dass sie nie verstümmelt angezeigt werden. In der Konsole ist mir das noch nicht gelungen!

Ich werde mich morgen mal Deinen Code probieren und schauen wie es sich verhält, wenn ich den in meine Script packe, welches die Daten erfasst. Heute Abend aber nicht mehr.

Wenn ich das richtig verstehe, muss ich erst jede einzelne Variable ($title, $track, $artist, $album, $comment, $year, $genre) prüfen und gegenbenenfalls konvertieren bevor ich die in $Text zusammenfasse.

Grüße.
craano.

undefined
24-02-2007, 11:33
............
Wenn ich das richtig verstehe, muss ich erst jede einzelne Variable ($title, $track, $artist, $album, $comment, $year, $genre) prüfen und gegenbenenfalls konvertieren bevor ich die in $Text zusammenfasse.

Grüße.
craano.

Genau das wollen wir ja vermeiden ;)

Wenn du auf utf8 umsteigst solltest du folgendes beachten.
Ich gehe jetzt mal von der Bisherigen Beschreibung aus.
MySQL/Perl/WWW und Console.

* Die MySQL Datenbank Sollte in utf8 sein. Seit MySQL 4.1 ist das kein Problem mehr.
* Dein Script sollte beim Editieren auch auf utf8 stehen.
* Der Webserver sollte CHARSET utf8 ausgeben damit Umlaute richtig an den Browser Übermittelt werden und dieser den Zeichensatz Korrekt setzen kann.
* In der Console haben wir nun ein Problem. Wenn dein Linux kein UTF-8 in der Konsole Unterstützt gehe blos nicht einfach hin und Stelle um, das geht für den Rest der Umgebung nach hinten loss. Verwende hier am besten einen Converter wie iconv,icu oder recode.

craano
24-02-2007, 14:48
* Dein Script sollte beim Editieren auch auf utf8 stehen.


?
Kann ich das global in dem Skript einstellen?

Grüße.
craano.

undefined
24-02-2007, 16:08
Ein guter Editor sollte das schon können.
Welchen verwendest du den?

craano
24-02-2007, 17:30
Ein guter Editor sollte das schon können.
Welchen verwendest du den?

Bluefish, vim, gedit, kate.

In der Rehenfolge. Kommt immer darauf an, welcher verfügbar ist.

Aber ich stehe jetzt völlig auf dem Schlauch, ich dachte immer das sei ein Problem, woher die Daten stammen, wie sie eingelesen werden und wie sie gespeichert werden. Was hat denn der Editor damit zu tun. Oder meinst Du den Editor, welcher hinterher die Datei anzeigt?

Grüße.
craano.

undefined
25-02-2007, 00:13
Schon richtig, die meisten Unix/Linux Editoren erkennen den Zeichensatz und Verwenden ihn dann auch. Unter Kate kannst du z.B unter Extras Codierung nachsehen welcher Type Gerade Verwendet wird und unter Einstellungen Speichern legst du den Standard fest.
Hat iconv dir weiter geholfen?
mal Ein Beispiel Header


#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

print "Content-Type: text/html; charset=UTF-8;\n\n";

print <<"AUSGABE";
Meine Ausgabe mit Umlauten öäüÜÖÄß
AUSGABE