Alexander (HH): umlaut in regulärem Ausdruck

Beitrag lesen

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

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".