umlaut in regulärem Ausdruck
Armin
- perl
Hallo,
ich möchte dass ein Wort exakt in einem String gefunden wird, dazu benutze ich die Wortgrenze \b
Das funktioniert auch herforagend, solange das gesuchte Wort nicht mit einem Umlaut beginnt. In dem Beispiel wird das Wort "auto" erwartungsgemäss ersetzt, das wort "über" jedoch nicht.
$satz="Das Wort auto wird gefunden autobahn aber nicht";
$wort="auto";
$change="test";
$satz=~s/\b$wort\b/$change/g;
print "$satz\n";
$satz="Das Wort über wird gefunden überholen aber nicht";
$wort="über";
$change="test";
$satz=~s/\b$wort\b/$change/g;
print "$satz\n";
Wie kann ich das umgehen?
Gruß,
Armin
@@Armin:
nuqneH
ich möchte dass ein Wort exakt in einem String gefunden wird, dazu benutze ich die Wortgrenze \b
Das funktioniert auch herforagend, solange das gesuchte Wort nicht mit einem Umlaut beginnt.
Die englischsprachigen Entwickler haben nicht über ihren Tellerrand hinausgeschaut. Wie ich in einem Thread zum ähnlichen Thema schon sagte: „Man sollte allen, deren Muttersprache Englisch ist, zumindest das Implementieren von Stringverarbeitung verbieten.“
Qapla'
Hallo,
danke für die Info. Dann kann ich \b sozusagen vergessen und muss veruchen das irgendwie anders hinzubasteln.
Gruß,
Armin
Moin Moin!
»» ich möchte dass ein Wort exakt in einem String gefunden wird, dazu benutze ich die Wortgrenze \b
»» Das funktioniert auch herforagend, solange das gesuchte Wort nicht mit einem Umlaut beginnt.Die englischsprachigen Entwickler haben nicht über ihren Tellerrand hinausgeschaut.
Falsch. So beschränkt ist zwar Javascript, aber Perl KANN mit anderen Sprachen umgehen. Man muß Perl nur mitteilen, dass man auf Deutsch arbeiten möchte:
#!/bin/bash
env -i LC_ALL=de_DE /usr/bin/perl -e ' $_="abcädef ghißjkl";s/\b/*/g;print"$_\n"'
env -i LC_ALL=de_DE /usr/bin/perl -e 'use locale;$_="abcädef ghißjkl";s/\b/*/g;print"$_\n"'
Beide Demonstrationen ersetzen Wortgrenzen (\b) durch Sterne. Ohne Locale zählen ä und ß als Nicht-Wortzeichen, mit deutscher Locale zählen sie als Wortzeichen. Entsprechend sieht das Ergebnis aus:
*abc*ä*def* *ghi*ß*jkl*
*abcädef* *ghißjkl*
Das geht natürlich auch zur Laufzeit:
#!/usr/bin/perl -w
use locale;
use POSIX qw(locale_h);
setlocale(LC_ALL,'de_DE');
{
no locale;
$_="abcädef ghißjkl";
s/\b/*/g;
print"$_\n";
}
{
use locale;
$_="abcädef ghißjkl";
s/\b/*/g;
print"$_\n";
}
Alexander
@@Alexander (HH):
nuqneH
Ohne Locale zählen ä und ß als Nicht-Wortzeichen, mit deutscher Locale zählen sie als Wortzeichen.
Hm, das ist eigentlich nicht das, was man will. Das hieße doch, bei deutscher Locale wäre 'ä' ein Wortzeichen, 'д' jedoch nicht. Bei russischer Locale andersrum. Für gemischtsprachige Texte ziemlich unbrauchbar.
Gibt es auch eine Einstellung, bei der alle Buchstaben aller Schriften (lateinisch, kyrillisch, griechisch, hebräisch, arabisch, chinesisch, japanisch, …) als Wortzeichen zählen?
Qapla'
Moin Moin!
@@Alexander (HH):
nuqneH
»» Ohne Locale zählen ä und ß als Nicht-Wortzeichen, mit deutscher Locale zählen sie als Wortzeichen.
Hm, das ist eigentlich nicht das, was man will.
In aller Regel doch. Man arbeitet zu einem Zeitpunkt nur mit einer Sprache. In den Sonderfällen, in denen man mehrere Sprachen in einem String/in einer Datei hat, muß man den String/die Datei nach Sprachen trennen und dann jeweils auf die passende Locale umschalten.
Es wäre natürlich einfacher, wenn man einem Scalar einen Satz Locale-Daten mitgeben könnte, der dann z.B. bei RegExps automatisch benutzt wird. Vielleicht in Perl6. Bis dahin würde ich bei einem Programm, dass massiv mit Locale und mehreren Sprachen arbeitet, mir vermutlich ein String-Objekt basteln, dass genau diese Eigenschaft hat, und das z.B. auch eine eigene Substitutionsmethode (s///) hätte.
Das hieße doch, bei deutscher Locale wäre 'ä' ein Wortzeichen, 'д' jedoch nicht. Bei russischer Locale andersrum. Für gemischtsprachige Texte ziemlich unbrauchbar.
Das Locale-System ist nicht perfekt. Das ist sogar als Bug dokumentiert.
Gibt es auch eine Einstellung, bei der alle Buchstaben aller Schriften (lateinisch, kyrillisch, griechisch, hebräisch, arabisch, chinesisch, japanisch, …) als Wortzeichen zählen?
Man könnte sich eine neue Locale zusammenbasteln, die wenigstens die für das Projekt benötigten Sprachen zusammenmischt. Locale ist aber nicht nur für die Anpassung der CTYPEs da (LC_CTYPE), sondern macht mehr: Datumsformate (LC_TIME, d/m/y, m/d/y oder y/m/d?), Zahlenformate (LC_NUMERIC, 10.000.000 oder 10,000,000 oder 1,00,00,00?), Währungsformate (LC_MONETARY, $-100,00 oder -100,00$ oder 100,00$-?) und Sortierung bzw. Case-Umwandlung (LC_COLLATE, ä als a oder ä als ae oder ä nach z? Was ist das Zeichen für uc('ß')? Was ist das Zeichen für uc('i') -- im Türkischen ein I mit einem Punkt darüber!). Da wird es dann schon wieder schwierig. Wie ist *DAS* Zahl-, Währungs- und Datumsformat für ALLE Sprachen? Wie ist *DIE* Sortierreihenfolge für alle Sprachen?
Alexander
@@Alexander (HH):
nuqneH
Man arbeitet zu einem Zeitpunkt nur mit einer Sprache.
Nein. Was, wenn in einem Text mal ein Wort aus einer anderen Sprache vorkommt, bspw. ein Eigenname (Stadt, Person)?
In den Sonderfällen, in denen man mehrere Sprachen in einem String/in einer Datei hat, muß man den String/die Datei nach Sprachen trennen und dann jeweils auf die passende Locale umschalten.
Nicht wirklich praktikabel.
Es wäre natürlich einfacher, wenn man einem Scalar einen Satz Locale-Daten mitgeben könnte, der dann z.B. bei RegExps automatisch benutzt wird.
Nein. RegExps sollten alle Zeichen, die in Unicode als "Ll Letter, lowercase", "Lu Letter, uppercase" oder "Lo Letter, other" gekennzeichnet sind, auch als Buchstaben = Wortzeichen akzeptieren. (Richard Ishidas UniView zeigt die "General category" mit an.)
Locale ist aber nicht nur für die Anpassung der CTYPEs da (LC_CTYPE), sondern macht mehr: Datumsformate (LC_TIME, d/m/y, m/d/y oder y/m/d?), Zahlenformate (LC_NUMERIC, 10.000.000 oder 10,000,000 oder 1,00,00,00?), Währungsformate (LC_MONETARY, $-100,00 oder -100,00$ oder 100,00$-?) und Sortierung bzw. Case-Umwandlung (LC_COLLATE, ä als a oder ä als ae oder ä nach z?
Eben. Locales sind gut für alles mögliche, aber nicht dafür, welche Zeichen Buchstaben sind. Das regelt Unicode.
Qapla'
Moin Moin!
Nein. RegExps sollten alle Zeichen, die in Unicode als "Ll Letter, lowercase", "Lu Letter, uppercase" oder "Lo Letter, other" gekennzeichnet sind, auch als Buchstaben = Wortzeichen akzeptieren. (Richard Ishidas UniView zeigt die "General category" mit an.)
[...] Locales sind gut für alles mögliche, aber nicht dafür, welche Zeichen Buchstaben sind. Das regelt Unicode.
Wie schön wäre die Welt, wenn man sich noch vor der Definition von ASCII gleich auf darauf geeinigt hätte, dass ein Character mindestens 32 Bit groß und nach Unicode definiert ist.
Leider haben wir aber jede Menge Encodings aus der Zeit vor Unicode, und mit denen müssen wir (und Perl) arbeiten.
So lange Du nicht explizit mit Unicode arbeitest, ist das Locale-System zwar nicht schön, aber das Beste, was verfügbar ist. (Wobei "das Beste" nicht bedeutet, dass es "gut" ist. Es fehlt einfach an besseren Alternativen.) Mit set_locale legst Du fest, welche Bytes Buchstaben sind und welche nicht, denn nirgendwo sonst gibt es diese Information. Man könnte auf die Idee kommen, die Daten erstmal nach Unicode zu konvertieren, die Unicode-Informationen zu konsultieren, und das Ergebnis wiederzurück zu konvertieren. Das dürfte nicht nur ziemlich langsam sein, sondern es fehlt hier schlicht die Angabe, welches Encoding vorliegt.
Mit Unicode sieht das alles ganz anders aus, siehe perlunicode:
The regular expression compiler produces polymorphic opcodes. That is, the pattern adapts to the data and automatically switches to the Unicode character scheme when presented with data that is internally encoded in UTF-8 -- or instead uses a traditional byte scheme when presented with byte data.
Perl aims to provide a safe migration path from byte semantics to character semantics for programs. For operations where Perl can unambiguously decide that the input data are characters, Perl switches to character semantics. For operations where this determination cannot be made without additional information from the user, Perl decides in favor of compatibility and chooses to use byte semantics.
Effects of Character Semantics:
Character classes in regular expressions match characters instead of bytes and match against the character properties specified in the Unicode properties database. \w can be used to match a Japanese ideograph, for instance.
Oder, um Code sprechen zu lassen:
#!/usr/bin/perl -w
$_=substr("\x{0100}abc\x{00E4}def ghi\x{00DF}jkl",1); # <--(1)
s/\b/*/g;
print"$_\n";
(1) Perl optimiert hier zu gut und speichert "abc\x{00E4}def ghi\x{00DF}jkl" als Byte-String ohne UTF8-Flag ("character semantics"). Erst das zusätzliche Unicode-Zeichen U+0100 setzt das UTF8-Flag, substr entfernt dann das Zeichen, es bleibt "abcädef ghißjkl" mit UTF8-Flag in $_ übrig.
(Der Umweg über die \x{XXXX}-Notation ist eigentlich unnötig, aber so kann ich sicher sein, dass auch mit Copy&Paste die richtigen Zeichen bei Perl ankommen.)
Ausgabe:
*abcädef* *ghißjkl*
bzw.
*abcΣdef* *ghi▀jkl*
unter Windows (wegen Encoding-Problemen der DOS-Box dort).
Alexander
Nein. RegExps sollten alle Zeichen, die in Unicode als "Ll Letter, lowercase", "Lu Letter, uppercase" oder "Lo Letter, other" gekennzeichnet sind, auch als Buchstaben = Wortzeichen akzeptieren. (Richard Ishidas UniView zeigt die "General category" mit an.)
Toll. Perl müsste dann bei jedem Scriptaufruf eine Bibliothek von mehreren Tausenden Unicodes laden, um Regex parsen zu können. Schlimmer noch, diese Bibliothek ist in permanenter Entwicklung.
Wenn dies schon wünschbar wäre, warum dann nur ein \b und ein \w
Wären andere Nullweite Unicode-Klassengrenzen nicht auch wünschbar? Den Preis hast du ja schon bezahlt.
Das ist der Grund warum ich postuliere:
\w ist in ASCII [A-Za-z0-9_] und \b ist die Grenze zwischen \W und \w oder zwischen \w und \W. Alles andere ist nicht konsistent ausführbar.
Recht gebe ich darin, dass locale in CGI keinen Sinn macht. In einem Netzwerk möchte ich Konsistenz unabhängig der lokalen Maschine.
mfg Beat
Moin Moin!
»» Nein. RegExps sollten alle Zeichen, die in Unicode als "Ll Letter, lowercase", "Lu Letter, uppercase" oder "Lo Letter, other" gekennzeichnet sind, auch als Buchstaben = Wortzeichen akzeptieren. (Richard Ishidas UniView zeigt die "General category" mit an.)
Toll. Perl müsste dann bei jedem Scriptaufruf eine Bibliothek von mehreren Tausenden Unicodes laden, um Regex parsen zu können. Schlimmer noch, diese Bibliothek ist in permanenter Entwicklung.
Richtig.
Wenn dies schon wünschbar wäre, warum dann nur ein \b und ein \w
Wären andere Nullweite Unicode-Klassengrenzen nicht auch wünschbar? Den Preis hast du ja schon bezahlt.
So wie ich Unicode Regular Expression Support Level lese, sind solche Dinge zwar vorgesehen, aber noch nicht implementiert.
Das ist der Grund warum ich postuliere:
\w ist in ASCII [A-Za-z0-9_]
Nur, wenn die C-Locale aktiv ist und Unicode seine Finger nicht im Spiel hat. Oder wenn Du Dich mit Javascript rumschlagen mußt.
perlre definiert \w ganz bewußt als 'alphanumeric plus "_"', was Buchstaben und Ziffern außerhalb des ASCII-Bereichs NICHT ausschließt.
\W ist als 'non-"word" character' definiert, matcht also alle Zeichen, die \w nicht matcht.
und \b ist die Grenze zwischen \W und \w oder zwischen \w und \W.
Exakt das ist die Definition von \b: A word boundary (\b) is a spot between two characters that has a \w on one side of it and a \W on the other side of it (in either order), counting the imaginary characters off the beginning and end of the string as matching a \W .
Alles andere ist nicht konsistent ausführbar.
Das einzige Problem hier ist die Definition von \w. Die ist traditionell, ohne Locale und Unicode zu berücksichtigen, [A-Za-z0-9_], und das ist auch ein guter Default. Für Programme, die sich nicht nur mit englischen Texten befassen, muß dieser Default änderbar sein.
Recht gebe ich darin, dass locale in CGI keinen Sinn macht.
Was an der CGI-Spezifikation definiert, dass Du keine sprach- bzw. landesabhängigen Einstellungen haben darfst? FastCGIs und mod_perl-Anwendungen dürften dann wieder Locale benutzen?
In einem Netzwerk möchte ich Konsistenz unabhängig der lokalen Maschine.
Dann definierst Du Dir am einfachsten Deine eigenen Character-Klassen oder verwendest konsequent Unicode und \p{L} / \P{L} statt \w und \W.
Alexander
你好 Beat,
Toll. Perl müsste dann bei jedem Scriptaufruf eine Bibliothek von mehreren Tausenden Unicodes laden, um Regex parsen zu können.
Nö – die Kategorie eines Zeichens ist via Bitweisem UND abfragbar, da entsprechend die (meisten) Attribute in einem Codepoint als ein ein- bzw. ausgeschaltetes Bit repräsentiert sind.
Schlimmer noch, diese Bibliothek ist in permanenter Entwicklung.
Das ist natürlich wahr.
再见,
克里斯蒂安
Hallo Alexander!
*abc*ä*def* *ghi*ß*jkl*
*abcädef* *ghißjkl*
Das geht natürlich auch zur Laufzeit:
»» {
> use locale;
> $_="abcädef ghißjkl";
> s/\b/*/g;
> print"$_\n";
> }
>
Dieser print ergibt bei mir:
*abc*ä*def* *ghißjkl*
Windows Vista und XP (andere Umlaute dito).
Viele Grüße aus Frankfurt/Main,
Patrick
Moin Moin!
»» *abc*ä*def* *ghi*ß*jkl*
»» *abcädef* *ghißjkl*
»» Das geht natürlich auch zur Laufzeit:
»» {
»» use locale;
»» $="abcädef ghißjkl";
»» s/\b/*/g;
»» print"$\n";
»» }
»»
>
> Dieser print ergibt bei mir:
>
> \*abc\*ä\*def\* \*ghißjkl\*
>
> Windows Vista und XP (andere Umlaute dito).
Hmmm, Strawberry Perl 5.10.0 auf W2K geht problemlos. Vermutlich, weil es eine eigene Locale-DB in C:\strawberry\c\share\locale mitbringt.
Irgendwelche Warnungen? $ENV{LANG} oder irgendeine LC\_xxx-Environment-Variablen gesetzt?
Das große Problem bei locale ist eben, dass das locale-System alles andere als perfekt ist, das deutet [perllocale](http://perldoc.perl.org/perllocale.html) ja schon an.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
Hallo Alexander!
Irgendwelche Warnungen
Nein...
$ENV{LANG} oder irgendeine LC_xxx-Environment-Variablen gesetzt?
... auch nicht.
Viele Grüße aus Frankfurt/Main,
Patrick
Moin Moin!
»» Irgendwelche Warnungen
Nein...
»» $ENV{LANG} oder irgendeine LC_xxx-Environment-Variablen gesetzt?
... auch nicht.
Heißt Du vielleicht .... RUMPELSTILZCHEN?!
Äh, Moment! Falscher Text ...
Du benutzt nicht zufällig ActiveStates Perl-Version?
So wie ich das überblicke, hat Windows zwar einen Locale-artigen Mechanismus, aber wie so oft mal wieder selbstgestrickt statt Standard. Demzufolge müßte ActivePerl ohne Locale auskommen oder aber richtig perverse Sachen machen, um die entsprechende Windows-API auf die Locale-API umzustricken. Und das wäre reichlich viel Arbeit. Also werden die Locale-Funktionen wohl schlicht als Dummy implementiert sein.
Alexander
Hallo Alexander!
Heißt Du vielleicht .... RUMPELSTILZCHEN?!
Ach deswegen lachen alle, die meinen Ausweis sehen wollen ;)
Du benutzt nicht zufällig ActiveStates Perl-Version?
Genau. Auf allen Rechnern (2 Vista, 1 1/2 XP - »1 1/2« deshalb, weil mein uralter Schleppi aus allen Löchern pfeift *g*).
So wie ich das überblicke, hat Windows zwar einen Locale-artigen Mechanismus, aber wie so oft mal wieder selbstgestrickt statt Standard. Demzufolge müßte ActivePerl ohne Locale auskommen oder aber richtig perverse Sachen machen, um die entsprechende Windows-API auf die Locale-API umzustricken. Und das wäre reichlich viel Arbeit. Also werden die Locale-Funktionen wohl schlicht als Dummy implementiert sein.
Soweit reicht mein Wissen nicht. Ich muss mich auf Deine Aussage verlassen ;)
Viele Grüße aus Frankfurt/Main,
Patrick
Moin Moin!
»» Du benutzt nicht zufällig ActiveStates Perl-Version?
Genau. [...]
»» So wie ich das überblicke, hat Windows zwar einen Locale-artigen Mechanismus, aber wie so oft mal wieder selbstgestrickt statt Standard. Demzufolge müßte ActivePerl ohne Locale auskommen oder aber richtig perverse Sachen machen, um die entsprechende Windows-API auf die Locale-API umzustricken. Und das wäre reichlich viel Arbeit. Also werden die Locale-Funktionen wohl schlicht als Dummy implementiert sein.
perl -V:d_setlocale (title=hier geklaut)
ergibt bei Strawberry
d_setlocale='define';
ActivePerl müßte ohne setlocale-Support übersetzt sein, demzufolge müßte
perl -V:d_setlocale
dort
d_setlocale='undef';
liefern, schlimmstenfalls sogar
d_setlocale='UNKNOWN';
Entsprechend kann man das zur Laufzeit prüfen:
use Config ();
die 'No locale support' unless $Config::Config{'d_setlocale'} eq 'define';
Alexander
Hallo Alexander!
ActivePerl müßte ohne setlocale-Support übersetzt sein, demzufolge müßte
perl -V:d_setlocale
dort
d_setlocale='undef';
Niet:
d_setlocale='define';
Entsprechend kann man das zur Laufzeit prüfen:
use Config ();
die 'No locale support' unless $Config::Config{'d_setlocale'} eq 'define';
C:\>perl -w
use Config ();
die 'No locale support' unless $Config::Config{'d\_setlocale'} eq 'define';
^Z
C:\>
Kein Sterbenswörtchen ;)
Viele Grüße aus Frankfurt/Main,
Patrick
--
\_ - jenseits vom delirium - \_
![](http://www.atomic-eggs.com/fuernA.jpg)
[Diblom](http://www.atomic-eggs.com/pics/diblom.png) [[link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash](http://www.atomic-eggs.com/)]
[J'ai 10 ans!](http://www.atomic-eggs.com/wae/wae_10.shtml#a5) | Achtung [Agentur](http://www.atomic-eggs.com/cwi/cwi_5.shtml#a5)! | Nichts ist unmöglich? [Doch!](http://www.atomic-eggs.com/cwi/cwi_4.shtml) | [Heute](http://www.atomic-eggs.com/cgi-bin/date_today.pl) schon ge[gök](http://goek.atomic-eggs.com/goek_goek.html)t?
Moin Moin!
Hallo Alexander!
»» ActivePerl müßte ohne setlocale-Support übersetzt sein, demzufolge müßte
»»
»» perl -V:d_setlocale
»»
»» dort
»»
»» d_setlocale='undef';Niet:
d_setlocale='define';
Merkwürdig. Da scheint das Setzen der Locale auf die Nase zu fallen, und Perl gibt keinen Mucks von sich. Ich hätte die Meldung unter http://perldoc.perl.org/perllocale.html#LOCALE-PROBLEMS erwartet.
perl -V ?
Alexander
Hallo Alexander!
perl -V ?
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. Alle Rechte vorbehalten.
C:>perl -V
Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
Platform:
osname=MSWin32, osvers=5.00, archname=MSWin32-x86-multi-thread
uname=''
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=undef, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cl', ccflags ='-nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -
DNO_STRICT -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IM
PLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX',
optimize='-MD -Zi -DNDEBUG -O1',
cppflags='-DWIN32'
ccversion='12.00.8804', gccversion='', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksi
ze=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -libpath:"C:
\Perl\lib\CORE" -machine:x86'
libpth=\lib
libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32
.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_
32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comd
lg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib
ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl510.lib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -
libpath:"C:\Perl\lib\CORE" -machine:x86'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS
USE_LARGE_FILES USE_PERLIO USE_SITECUSTOMIZE
Locally applied patches:
ActivePerl Build 1004 [287188]
33741 avoids segfaults invoking S_raise_signal() (on Linux)
33763 Win32 process ids can have more than 16 bits
32809 Load 'loadable object' with non-default file extension
32728 64-bit fix for Time::Local
Built under MSWin32
Compiled at Sep 3 2008 13:16:37
@INC:
C:/Perl/site/lib
C:/Perl/lib
.
Viele Grüße aus Frankfurt/Main,
Patrick
你好 Patrick,
unter Windows musst du die Locale-Namen verwenden, die Windows benutzt. Welche das sind, kannst du in der MSDN nachlesen:
http://msdn.microsoft.com/en-us/library/cdax410z(vs.71).aspx
http://msdn.microsoft.com/en-us/library/39cwe7zf(vs.71).aspx
'deu_deu' müsste z. B. gehen.
再见,
克里斯蒂安
Moin Moin!
unter Windows musst du die Locale-Namen verwenden, die Windows benutzt. Welche das sind, kannst du in der MSDN nachlesen:
http://msdn.microsoft.com/en-us/library/cdax410z(vs.71).aspx
http://msdn.microsoft.com/en-us/library/39cwe7zf(vs.71).aspx'deu_deu' müsste z. B. gehen.
Wäre ja auch langweilig, wenn so etwas OS-übergreifend mit identischen Strings funktionieren würde ...
Ich schätze, das betrifft "nur" ActivePerl, den Strawberry bringt definitiv seine eigene Locale-DB mit (in C:\strawberry\c\share\locale).
Ich hab im Moment leider keinen Rechner mit ActivePerl, mir ist die Suche nach PPMs auf Dauer zu blöd geworden. Strawberry bringt einen brauchbaren Compiler samt Make-Implementation mit, damit kann ich direkt von CPAN installieren.
Patrick, teste doch bitte mal mit den Locale-Settings aus der MSDN.
Alexander
你好 Alexander,
Wäre ja auch langweilig, wenn so etwas OS-übergreifend mit identischen Strings funktionieren würde ...
Locales sind in höchstem Maße maschinen(!)-abhängig. Jeder Administrator kann seine Locales so nennen, wie er es mag. Deshalb sollte, wenn man Locales selber setzt, man immer die Option anbieten, es via Konfiguration zu ändern.
Locales sind ja nicht dazu gedacht, dass man sie in einem Programm setzt, sondern sie sollen transparent funktionieren. Üblicherweise setzt der Nutzer ja das Locale in seiner Umgebung auf die Sprache, die er verwendet.
Ich schätze, das betrifft "nur" ActivePerl, den Strawberry bringt definitiv seine eigene Locale-DB mit (in C:\strawberry\c\share\locale).
Könnte sein, ist aber einige Zeit her, dass ich zuletzt Perl unter Windows genutzt habe (wobei: richtiger wäre, „dass ich zuletzt Windows benutzt habe”), kann ich also nicht beurteilen.
再见,
克里斯蒂安
Patrick, teste doch bitte mal mit den Locale-Settings aus der MSDN.
Ich bin zwar nicht Patrick, hab's trotzdem mal getestet. Leider keine Veränderung in der Konsole mit deu_deu oder deu :-(
Aber! Ich vermute das hängt mit der Konsole bzw. dem Zeichensatz dort zusammen. Denn als CGI funktionert bei mir tadelos:
use strict;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
print CGI::header(), CGI::start_html();
use locale;
$_="abcädef ghißjkl";
s/\b/*/g;
print"$_\n";
print CGI::end_html();;
Struppi.
Moin Moin!
»» Patrick, teste doch bitte mal mit den Locale-Settings aus der MSDN.
Ich bin zwar nicht Patrick, hab's trotzdem mal getestet. Leider keine Veränderung in der Konsole mit deu_deu oder deu :-(
Aber! Ich vermute das hängt mit der Konsole bzw. dem Zeichensatz dort zusammen. Denn als CGI funktionert bei mir tadelos:
Das will ich um diese Uhrzeit gar nicht mehr verstehen. Und überhaupt, immer wenn ich versuche, nachzuvollziehen, was sich die MS-Entwickler rund um Windows so ausgedacht haben, bekomme ich Kopfschmerzen.
Interessant wäre noch zu sehen, was passiert, wenn Windows überhaupt keine Konsole öffnet. AP hatte lange Zeit ein wperl.exe dabei, das bis auf ein Feld im Header mit perl.exe übereinstimmt. wperl.exe identifiziert sich als "windowed application", während perl.exe eine "console application" ist. Ein Tool namens exetype.pl kann zwischen beiden Varianten umpatchen.
Wenn also das Vorhandensein bzw. Initialisieren der Konsole Einfluß hat, müßte ein direkter Aufruf über wperl.exe (z.B. via Start->Run oder Drag-and-Drop des Scripts auf wperl.exe) ein anderes Ergebnis bringen. Um etwas zu sehen, würde ich Win32::MsgBox statt print benutzen oder in eine Temp-Datei schreiben.
Nur: Normalerweise startet der Webserver perl.exe, nicht wperl.exe. Aber der Webserver kann (als Service) mangels Zugriff auf den Desktop keine Konsole öffnen.
Und schon fangen die Kopfschmerzen wieder an ... ;-)
Alexander
Interessant wäre noch zu sehen, was passiert, wenn Windows überhaupt keine Konsole öffnet. AP hatte lange Zeit ein wperl.exe dabei, das bis auf ein Feld im Header mit perl.exe übereinstimmt. wperl.exe identifiziert sich als "windowed application", während perl.exe eine "console application" ist. Ein Tool namens exetype.pl kann zwischen beiden Varianten umpatchen.
Das Problem dürfte nicht die Konsole an sich sein. Sondern das kopieren und der Aufruf direkt im perl interpreter in der Konsole
Also wenn ich das folgende Skript:
use locale;
$_="abcädef ghißjkl";
s/\b/*/g;
print ;
Mit Notepad++ in ANSI abspeicher und in der Konsole starte, kommt das raus:
C:\...\t.pl
*abcõdef* *ghi▀jkl*
Funktioniert also, nur die Umlaute werden in der DOS Box logischerweise falsch dargestellt.
Wenn ich's aber direkt in Perl starte:
C:\>...\perl
use locale;
$_="abcädef ghißjkl";
s/\b/*/g;
print ;
^Z
*abc*ä*def* *ghißjkl*
Funktioniert es nicht, dafür stimmen die Umlaute - sind dann wohl in CP-irgendwas.
Und schon fangen die Kopfschmerzen wieder an ... ;-)
Da fange ich mir gar nicht erst an Gedanken drüber zu machen. Für meine Zwecke hat bisher use locale gereicht und wenn's mal hakt, Frage ich hier ;-)
Struppi.
Moin Moin!
Das Problem dürfte nicht die Konsole an sich sein. Sondern das kopieren und der Aufruf direkt im perl interpreter in der Konsole
Also wenn ich das folgende Skript:
use locale;
$_="abcädef ghißjkl";
s/\b/*/g;
print ;
>
> Mit Notepad++ in ANSI abspeicher und in der Konsole starte, kommt das raus:
>
> ~~~perl
C:\...\t.pl
> *abcõdef* *ghi▀jkl*
>
Funktioniert also, nur die Umlaute werden in der DOS Box logischerweise falsch dargestellt.
Puuuuuh, genau damit habe ich eigentlich gerechnet. Wenn Du die Ausgabe in eine Datei umleitest und wieder mit dem Editor als ANSI öffnest, solltest Du auch wieder heile Umlaute sehen.
Wenn ich's aber direkt in Perl starte:
C:>...\perl
use locale;
$_="abcädef ghißjkl";
s/\b//g;
print ;
^Z
abcädef* ghißjkl
> Funktioniert es nicht, dafür stimmen die Umlaute - sind dann wohl in CP-irgendwas.
Genau, irgendwelche automatischen Konvertierungen beim Eingeben in der DOS-Box machen aus einem ANSI-ä (Windows-1252, Zeichen 228) ein OEM-ä (CP-437 oder CP-850, Zeichen 132). Perl arbeitet mit ANSI und erkennt das OEM-ä als ANSI-õ, das ist in der DE-Locate natürlich kein Wortzeichen. Gemeinerweise wird das, was Perl als ANSI-õ erkennt, in der DOS-Box natürlich wieder als OEM-ä angezeigt.
Und im Webserver/Webbroser ist natürlich erst einmal ISO-8859-1 angesagt, wenn nichts anderes angegeben ist. Windows-1252 ist ISO-8859-1, ergänzt um ein paar Definitionen zwischen 128 und 159, also gibt es keine Konvertierungsprobleme.
Patrick hat wohl Copy&Paste in die DOS-Box gemacht und damit ungewollt die Umlaute demoliert.
> »» Und schon fangen die Kopfschmerzen wieder an ... ;-)
Die Ursache ist hier also die selten dämliche Idee von Microsoft, auf der Kommandozeile einen anderen Zeichensatz als in der GUI zu benutzen. (Vom Standpunkt der DOS-Kompatibilität aus war das natürlich eine gute Idee.)
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
Dieser print ergibt bei mir:
*abc*ä*def* *ghißjkl*
Du hast vermutlich die Datei als utf-8 abgespeichert.
Struppi.
Hallo Struppi!
Du hast vermutlich die Datei als utf-8 abgespeichert.
Nein, direkt von hier kopiert und in die Konsole gepastet. Ein zweites Mal im Editor kopiert (um andere Umlaute im String zu tippen), er hat defaultmäßig windows 1252.
Viele Grüße aus Frankfurt/Main,
Patrick
@@Struppi:
nuqneH
Du hast vermutlich die Datei als utf-8 abgespeichert.
Was sollte die Zeichencodierung damit zutun haben?
Qapla'
Moin Moin!
»» Du hast vermutlich die Datei als utf-8 abgespeichert.
Was sollte die Zeichencodierung damit zutun haben?
Nichts, außer dass Perl die Codierung nicht unbedingt erkennt (kein BOM, kein use utf8;
, kein use encoding 'utf8';
). So steht dann zwar die UTF-8-Bytefolge im Speicher, aber Perl hält mangels UTF8-Flag am Scalar jeden Umlaut für zwei einzelne Zeichen (aus ISO-8859-1), von denen wenigstens eines bei de_DE nicht als Wort-Zeichen gilt.
Alexander