Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

uc() nicht auf Umlaute?

11 views
Skip to first unread message

Ulli Horlacher

unread,
Nov 14, 2009, 7:59:54 PM11/14/09
to
Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
korrekt gesetztem locale auch auf Umlaute wirken?

framstag@fex: echo "x����z" | perl -ne 'print uc'
X����Z

framstag@fex: perl -e 'print uc("x����z\n")'
X����Z

framstag@fex: locale
LANG=en_US.ISO8859-1
LC_CTYPE="en_US.ISO8859-1"
LC_NUMERIC="en_US.ISO8859-1"
LC_TIME="en_US.ISO8859-1"
LC_COLLATE="en_US.ISO8859-1"
LC_MONETARY="en_US.ISO8859-1"
LC_MESSAGES="en_US.ISO8859-1"
LC_PAPER="en_US.ISO8859-1"
LC_NAME="en_US.ISO8859-1"
LC_ADDRESS="en_US.ISO8859-1"
LC_TELEPHONE="en_US.ISO8859-1"
LC_MEASUREMENT="en_US.ISO8859-1"
LC_IDENTIFICATION="en_US.ISO8859-1"
LC_ALL=

Ausserdem matcht \w ebenfalls nicht auf Umlaute, sondern nur auf ASCII.
Gibts was besseres als [\w�-�] um alphanumerische Latin1 Zeichen zu
matchen?


--
Ullrich Horlacher Informationssysteme und Serverbetrieb
Rechenzentrum E-Mail: horl...@rus.uni-stuttgart.de
Universitaet Stuttgart Tel: ++49-711-685-65868
Allmandring 30 Fax: ++49-711-682357
70550 Stuttgart (Germany) WWW: http://www.rus.uni-stuttgart.de/

Tim Landscheidt

unread,
Nov 14, 2009, 8:11:26 PM11/14/09
to
Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:

> Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
> korrekt gesetztem locale auch auf Umlaute wirken?

> framstag@fex: echo "x����z" | perl -ne 'print uc'
> X����Z

> [...]

Du musst die Ein-/Ausgaben als UTF-8 deklarieren:

| [tim@passepartout ~]$ echo "x����z" | perl -CS -ne 'print uc'
| X����Z
| [tim@passepartout ~]$

Tim

David Haller

unread,
Nov 14, 2009, 11:30:46 PM11/14/09
to
Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
> korrekt gesetztem locale auch auf Umlaute wirken?
>
> framstag@fex: echo "xᅵᅵᅵᅵz" | perl -ne 'print uc'
> XᅵᅵᅵᅵZ

$ echo "xᅵᅵᅵᅵz" | perl -Mlocale -ne 'print uc'
XᅵᅵᅵᅵZ
$ perl --version | head -n 2

This is perl, v5.10.0 built for i686-linux-thread-multi-64int-ld
$ locale
LANG=en_US.ISO_8859-15
LC_CTYPE="en_US.ISO_8859-15"
LC_NUMERIC="en_US.ISO_8859-15"
LC_TIME="en_US.ISO_8859-15"
LC_COLLATE=POSIX
LC_MONETARY="en_US.ISO_8859-15"
LC_MESSAGES="en_US.ISO_8859-15"
LC_ALL=

Explizit gesetzt sind nur LANG und LC_COLLATE. libc ist GNU libc
2.1.3. War auch schon bei deutlich ᅵlteren perl 5.x so:

$ echo "xᅵᅵᅵᅵz" | PERL5LIB= /usr/bin/perl5.00503 -Mlocale -ne 'print uc'
XᅵᅵᅵᅵZ

Mit UTF-8 klappte das damals aber noch nicht so einfach:

$ echo "xᅵᅵᅵᅵz" | recode latin9..UTF-8 | LANG=de_DE.UTF-8 \
PERL5LIB= /usr/bin/perl5.00503 -Mlocale -ne 'print uc' | \
recode UTF-8..latin9
XᅵᅵᅵᅵZ

Auf nem aktuellen Linux mit GNU libc 2.9 / gcc 4.3.2 / perl 5.10.0
ist's auch nicht anders:

$ echo "xᅵᅵᅵᅵz" | perl -ne 'print uc'
XᅵᅵᅵᅵZ
$ echo "xᅵᅵᅵᅵz" | perl -Mlocale -ne 'print uc'
XᅵᅵᅵᅵZ

HTH,
-dnh

--
Ein Hund denkt: Sie fᅵttern mich, sie sorgen fᅵr mich, sie streicheln
mich: das mᅵssen Gᅵtter sein.
Eine Katze denkt: Sie fᅵttern mich, sie sorgen fᅵr mich, sie streicheln
mich: ich muss ein Gott sein. -- Konni Scheller

Ulli Horlacher

unread,
Nov 15, 2009, 4:15:19 AM11/15/09
to
Tim Landscheidt <t...@tim-landscheidt.de> wrote:
> Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
>
> > Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
> > korrekt gesetztem locale auch auf Umlaute wirken?
>
> > framstag@fex: echo "x����z" | perl -ne 'print uc'
> > X����Z
> > [...]
>
> Du musst die Ein-/Ausgaben als UTF-8 deklarieren:

Nein. Ich hab kein UTF-8, sondern ISO-Latin-1.

Message has been deleted

Ulli Horlacher

unread,
Nov 15, 2009, 7:25:32 AM11/15/09
to
Michael Holzt <sp...@fqdn.org> wrote:

> Ulli Horlacher wrote:
> > Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
> > korrekt gesetztem locale auch auf Umlaute wirken?
>
> Der Teil mit "korrekt gesetzt" k�nnte den Nagel auf den Kopf treffen.
>
> > LANG=en_US.ISO8859-1
>
> Zumindest auf meinem System w�re es korrekterweise "en_US.ISO-8859-1".

Nein, en_US.ISO8859-1 ist bei mir richtig.

Ulli Horlacher

unread,
Nov 15, 2009, 7:26:05 AM11/15/09
to
David Haller <dha...@spamgourmet.com> wrote:
> Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> > Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
> > korrekt gesetztem locale auch auf Umlaute wirken?
> >
> > framstag@fex: echo "x����z" | perl -ne 'print uc'
> > X����Z
>
> $ echo "x����z" | perl -Mlocale -ne 'print uc'
^^^^^^^^

TatatATAAA! Das wars :-)

Peter J. Holzer

unread,
Nov 15, 2009, 12:50:40 PM11/15/09
to
On 2009-11-15 09:15, Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> Tim Landscheidt <t...@tim-landscheidt.de> wrote:
>> Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
>> > Ich dachte eigentlich bisher, dass die Funktionen uc() und lc() bei
>> > korrekt gesetztem locale auch auf Umlaute wirken?

Sie wirken auch ohne locale wenn Du sie auf einen Character-String
anwendest. Bei einem Byte-String wei� Perl (ohne Locale-Information) ja
nicht, was die Bytes bedeuten sollen.


>> > framstag@fex: echo "x����z" | perl -ne 'print uc'
>> > X����Z
>> > [...]
>>
>> Du musst die Ein-/Ausgaben als UTF-8 deklarieren:
>
> Nein. Ich hab kein UTF-8, sondern ISO-Latin-1.

Dann musst Du es als ISO-Latin-1 deklarieren.

Mantra der korrekten Behandlung von Text in Perl:

Decode input, encode output.

(Siehe binmode, Perl I/O Layer)

"use locale" habe ich vor vielen Jahren als unbrauchbar abgehakt, ich
kann mich aber nicht mehr erinnern, warum. Wenn ich (was kaum mehr
vorkommt, ist inzwischen fast alles UTF-8) locale-spezifisches Encoding
brauche, dann mache ich das so:

use I18N::Langinfo qw(langinfo CODESET);
$encoding = langinfo(CODESET);
binmode STDIN, ":encoding($encoding)";
binmode STDOUT, ":encoding($encoding)";

hp

David Haller

unread,
Nov 15, 2009, 11:48:46 PM11/15/09
to
Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> Michael Holzt <sp...@fqdn.org> wrote:
>> Ulli Horlacher wrote:
>> > LANG=en_US.ISO8859-1
>> Zumindest auf meinem System wᅵre es korrekterweise "en_US.ISO-8859-1".

> Nein, en_US.ISO8859-1 ist bei mir richtig.

Die genaue Schreibweise variiert, oft werden auch mehrere
akzeptiert. Zum Beispiel:

.ISO8859-1, ISO-8859-1, ISO_8859-1, iso8859-1 ...
oder
.ISO8859-15, ISO-8859-15, ISO_8859-15, iso8859-15, @euro ...

je nach Art/Version der (g)libc ... Man mᅵge sich aus der Ausgabe von
'locale -m' oder den Dateinamen aus 'ls /usr/share/i18n/charmaps/'
ohne .gz eine passende Schreibweise heraussuchen ;)

Wichtiger ist, daᅵ man perl auch mitteilt, daᅵ man gedenkt, auf die
locales zuzugreifen ;)

Peter Holzer's Methode gibt mir ᅵbrigens ein falsches Encoding:

$ perl -e 'use I18N::Langinfo qw(langinfo CODESET);
print langinfo(CODESET), "\n";'
ISO-8859-1

Peter? (nein, da ist keine 5 verlorengeganen).

Ich verwende hier aber seit ca. 2003 durchgᅵngig ISO-8859-15, und LANG
ist / die locales sind auch passend gesetzt.

Ich halte es fᅵr sinnvoll, per default die System-locale zu verwenden,
eben z.B. durch das einfache 'use locale;', und generell (bei Bedarf)
per binmode/open _gezielt_ das encoding fᅵr die einzulesenden bzw.
auszugebenden Daten zu setzen, wenn die Daten eben nicht "lokaler"
Herkunft sind ;)

-dnh, meist mit glibc-2.1.3, LANG=en_US.ISO-8859-15 und z.B. perl
5.10.0 unterwegs

--
Was macht denn einen Sysadmin schneller munter
als eine Katze auf der Tastatur? -- Mark-Oliver Wolter

Peter J. Holzer

unread,
Nov 16, 2009, 4:48:31 PM11/16/09
to
On 2009-11-16 04:48, David Haller <dha...@spamgourmet.com> wrote:
> Peter Holzer's Methode gibt mir �brigens ein falsches Encoding:

>
> $ perl -e 'use I18N::Langinfo qw(langinfo CODESET);
> print langinfo(CODESET), "\n";'
> ISO-8859-1
>
> Peter? (nein, da ist keine 5 verlorengeganen).
>
> Ich verwende hier aber seit ca. 2003 durchg�ngig ISO-8859-15, und LANG

> ist / die locales sind auch passend gesetzt.

Ist eventuell eine der LC_*-Variablen anders gesetzt?

Hier funktioniert es auf Debian:

% LANG=en_US.iso88591
% ./printencoding
ISO-8859-1
% LANG=de_AT@euro
% ./printencoding
ISO-8859-15
% LANG=greek
% ./printencoding
ISO-8859-7

und Redhat:

% LANG=de_AT.iso885915@euro
% ./printencoding
ISO-8859-15
% LANG=zh_CN.gb2312
% ./printencoding
GB2312


> Ich halte es f�r sinnvoll, per default die System-locale zu verwenden,


> eben z.B. durch das einfache 'use locale;', und generell (bei Bedarf)

> per binmode/open _gezielt_ das encoding f�r die einzulesenden bzw.


> auszugebenden Daten zu setzen, wenn die Daten eben nicht "lokaler"
> Herkunft sind ;)
>
> -dnh, meist mit glibc-2.1.3, LANG=en_US.ISO-8859-15 und z.B. perl
> 5.10.0 unterwegs

glibc-2.1.3? Im Ernst? Die Version war bei Redhat 6.2 dabei, ebenso wie
perl 5.005. D�rfte also gute 10 Jahre alt sein. Da w�rde ich nicht
ausschlie�en, dass die einige Bugs im Locale-Handling hat.

hp

Message has been deleted
Message has been deleted

David Haller

unread,
Nov 16, 2009, 8:39:46 PM11/16/09
to
Peter J. Holzer <hjp-u...@hjp.at> wrote:
> On 2009-11-16 04:48, David Haller <dha...@spamgourmet.com> wrote:
>> Peter Holzer's Methode gibt mir ᅵbrigens ein falsches Encoding:

>>
>> $ perl -e 'use I18N::Langinfo qw(langinfo CODESET);
>> print langinfo(CODESET), "\n";'
>> ISO-8859-1
>>
>> Peter? (nein, da ist keine 5 verlorengeganen).
>>
>> Ich verwende hier aber seit ca. 2003 durchgᅵngig ISO-8859-15, und LANG

>> ist / die locales sind auch passend gesetzt.
>
> Ist eventuell eine der LC_*-Variablen anders gesetzt?

Nein.

$ locale
LANG=en_US.ISO-8859-15
LC_CTYPE="en_US.ISO-8859-15"
LC_NUMERIC="en_US.ISO-8859-15"
LC_TIME="en_US.ISO-8859-15"
LC_COLLATE=POSIX
LC_MONETARY="en_US.ISO-8859-15"
LC_MESSAGES="en_US.ISO-8859-15"
LC_ALL=

Explizit gesetzt sind nur LANG und LC_COLLATE.

[..]

>> -dnh, meist mit glibc-2.1.3, LANG=en_US.ISO-8859-15 und z.B. perl
>> 5.10.0 unterwegs
>
> glibc-2.1.3? Im Ernst? Die Version war bei Redhat 6.2 dabei, ebenso wie

> perl 5.005. Dᅵrfte also gute 10 Jahre alt sein. Da wᅵrde ich nicht
> ausschlieᅵen, dass die einige Bugs im Locale-Handling hat.

Jup und jup. Das wird's sein. Das System hab ich Sommer '99
installiert, noch mit glibc-2.1.2, nach ner Spielerei zum glibc-Update
(miᅵglᅵckt) hab ich dann die glibc-2.1.3 der SUSE 6.4 installiert ;)
Wie man schon am Perl und Kernel 2.4.37 sieht, aktualisiere ich aber
vieles ;)

Anderes System mit perl 5.10.0 und ner glibc-2.9:

$ locale
LANG=en_US.iso885915
LC_CTYPE="en_US.iso885915"
LC_NUMERIC="en_US.iso885915"
LC_TIME="en_US.iso885915"
LC_COLLATE=POSIX
LC_MONETARY="en_US.iso885915"
LC_MESSAGES="en_US.iso885915"
LC_PAPER="en_US.iso885915"
LC_NAME="en_US.iso885915"
LC_ADDRESS="en_US.iso885915"
LC_TELEPHONE="en_US.iso885915"
LC_MEASUREMENT="en_US.iso885915"
LC_IDENTIFICATION="en_US.iso885915"
LC_ALL=


$ perl -e 'use I18N::Langinfo qw(langinfo CODESET);
print langinfo(CODESET), "\n";'

ISO-8859-15

Explizit gesetzt LANG und LC_COLLATE. Passt. Vermutlich rechnet eben
keiner (zu Recht) mit so ner Kombination von perl und glibc
bzw. I18N::Langinfo fehlen die dafᅵr erforderlichen Sonderlocken.

Danke fᅵr's mitdenken!

-dnh, *das mit der glibc-Abhᅵngigkeit im Hinterkopf behalt*

--
Dinner not ready...(A)bort (R)etry (P)izza

Peter J. Holzer

unread,
Nov 19, 2009, 7:20:53 AM11/19/09
to
On 2009-11-17 01:02, Michael Holzt <sp...@fqdn.org> wrote:

> Peter J. Holzer wrote:
>> Hier funktioniert es auf Debian:
>> % LANG=en_US.iso88591
>
> Diese Schreibweise ist aber dennoch falsch. Siehe /usr/share/i18n/SUPPORTED.

Im Zweifelsfall verlasse ich mich lieber auf die Ausgabe von locale -a
als auf Doku.

hp

Message has been deleted

Peter J. Holzer

unread,
Nov 19, 2009, 5:56:24 PM11/19/09
to
> Gerade die Manpage von locale sagt aber, da� Du das eben nicht tun sollst.
>
>| /usr/share/i18n/SUPPORTED
>| List of supported values (and their associated encoding) for the locale
>| name. This representation is recommended over --all-locales one, due
>| being the system wide supported values.

Was auch immer dieser letzte Satz bedeuten mag.

> Wobei allerdings genaugenommen beides nicht zu vergleichen ist. locale -a
> gibt die Locales aus, die wirklich vorhanden (generiert) sind, w�hrend die
> Datei alle m�glichen enth�lt.

Das ist der Punkt. locale -a gibt mir die Locales aus, die auf diesem
System tats�chlich installiert sind. Wenn ich einen dieser Werte
verwende, funktioniert das sicher. Auf jeder Linux-Distribution, auf
HP-UX, Solaris, AIX, ...

Ein /usr/share/i18n/SUPPORTED hingegen gibt es weder unter HP-UX noch
unter RedHat Linux - das scheint Debian-spezifisch zu sein.


> locale -a gibt bei mir die Namen der vorhandenen locales �brigens
> ausnahmslos ohne Bindestriche aus. Dies legt die Vermutung nahe, da� diese
> einfach ignoriert werden

Mit der Vermutung d�rftest Du recht haben.
LANG=de_AT.U-T-F--8
funktioniert jedenfalls auch.

> Dann w�re Deine Angabe wohl auch richtig,

Die ist auf diesem System ganz sicher richtig, weil locale -a sie so
ausgibt. Also muss es auf diesem System eine Locale dieses Namens geben.

Hingegen steht "de_DE@euro" zwar im SUPPORTED-File, aber diese Locale
gibt es bei mir nicht (weil ich sie nicht generiert habe).

> wobei ich es mit Bindestrichen leichter lesbar finde.

Da stimme ich Dir zu.

hp

0 new messages