Zeichenkodierung
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
abstand
alpha
band
bandname
beitrag
break
buchstabe
einstellung
funktion
gruss
hilfe
iota
kodierung
letter
manual
match
tabelle
verstehe
ypsilon
zusatzzeichen
-
Hi,
ich hab folgendes Problem:
Ich möchte z.B. das russische Wort Темнозорь decodieren, d.h. jeden Buchstaben in seinen Code zerlegen.
Wie geht das?
mfg,
hr -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Ja, die hilft wirklich nicht weiter. Und ord() auch nicht.
-
Ja, dann weiß ich auch nicht weiter! Ist ja auch ein bischen schwierig mit russischen zeichen!
gruss computerfreak12 -
Ja das stimmt... ich hasse ASCII, alles is so kompliziert ... die hätten von Anfang an eine ASCII-Tabelle für "alle" Zeichen erschaffen sollen.
mfg,
hr -
Codierung von band namen der last.fm software.
Leider gibt es ja auch bands mit namen, die nicht ASCII-Zeichen enthalten ...
mfg,
hr -
Sollte eigendlich mit den UTF8 funktionen gehen
-
Russischen Text kanns in verschiedenen Kodierungen geben. Neben den am weitesten verbreiteten UTF-8 und Windows-1251 gibts noch diverse andere. Also müsstest du erstmal rausbekommen, in welcher Kodierung dein Text kommt.
Im Falle von UTF-8 könnte eventuell utf8-decode() weiterhelfen:
http://de.php.net/manual/de/function.utf8-decode.php
Allerdings bezweifle ich, dass du was Sinnvolles dabei rausbekommst. Denn Kyrillische Zeichen gibts im ISO-8859-1 nicht. Aber in diesen Zeichensatz konvertiert die genannte Funktion.
Hilfsweise hätte ich da noch eine Funktion namens foxy_utf8_to_nce(). Guckst du hier:
http://de.php.net/manual/de/function.imagettftext.php#57416
Die wandelt UTF-8-Text in ASCII um, aber behält Nicht-ASCII-Zeichenkodierungen und UTF-8-Kodierungen, indem sie sie in numerisch kodierte Entitäten (NCR) umwandelt -- also diese Dinger, die man in HTML-Quelltexten findet ("&#[Zahl];"). Die Funktion eignet sich zwar eher zur Darstellung von Texten im Web-Browser, aber man kann mit einem einfachen RegEx auch die speziell kodierten Zeichen wieder rausfischen ... -
Hi,
hey wow, die Funktion foxy_utf8_to_nce() ist ja genial ... echtes Kompliment meinerseits an dich alopex. Ich denke damit hat sich dieses Problem gelöst, ich muss die Funktion nur noch ein bischen umschreiben :). Wenn 'was nicht läuft, melde ich mich wieder.
mfg,
hr -
Hi,
hab' wieder ein Problem ...
Ich erklär kurz mal, was ich tun möchte, das ist am einfachsten:
Ich lese folgende Datei und möchte die Bandnamen (die Zeichenkette nach dem letzten Komma in jeder Zeile) mit strtolower() und ucwords() manipulieren ... dies ist eigentlich alles. Das Problem sind jetzt eben z.B. russische Zeichen (wie in der 2. Zeile der Datei).
http://ws.audioscrobbler.com/1.0/user/vast_/topartists.txt
Was muss ich genau tun, wenn ich die Bandnamen richtig manipulieren will?
<?php $band = 'Spezielle Zeichen ...'; // Bandname, gelesen aus DAtei $band = ucwords(strtolower($band)); // ... ?>
mfg,
hr
Beitrag geändert: 29.6.2007 15:44:49 von heavyraptor
Beitrag geändert: 29.6.2007 15:45:41 von heavyraptor -
Ähmmmm, auf Anhieb würde mir da nur ein von Hand erstelltes Array einfallen, dass als Keys die Kodierungen der Großbuchstaben und als Values die Kodierungen der entsprechenden Kleinbuchstaben hätte. Das kannst du dann mit einer selbstgebauten Funktion benutzen.
Die eingebauten Funktionen in PHP sind (für mich) da meist sehr komisch konstruiert. Mal können sie nur 8-Bit-Zeichensätze, mal ein bisschen mehr. Oft hängt es auch von den Einstellungen und den zur Verfügung stehenden Erweiterungen ab, wie etwas geht und ob was überhaupt geht.
http://de.php.net/manual/de/function.strtolower.php
strtolower() soll laut Handbuch von den locale-Einstellungen abhängen. Wenn es möglich ist, die auf Russisch einzustellen und du nur ASCII- und kyrillische Zeichen verwendest, könnte strtolower() funktionieren. Hab das aber noch nie ausprobiert, nur mal ein bisschen mit den locale-Einstellungen gespielt.
Einen Einstieg zu den diversen locale-Funktionen bietet
http://de.php.net/manual/de/function.setlocale.php
Eine andere Möglichkeit könnten die Multi-Byte-String-Funktionen sein. Dazu muss aber die passende Extension installiert sein:
http://de.php.net/manual/de/function.mb-strtolower.php
Manchmal hilft auch das Stöbern in den Benutzerkommentaren der diversen String-Funktionen. Wenn jemand anderes das gleiche Problem (oder ein ähnliches) hatte, findest du manchmal dort eine Lösung.
*Nachtrag*
Zum Beispiel die hier:
http://de.php.net/manual/de/function.strtolower.php#70981
Nee, die scheint nur mit 8-Bit-Kodierung zu funktionieren. Aber vielleicht die hier?
http://de.php.net/manual/de/function.strtolower.php#25335
Beitrag geändert: 29.6.2007 20:51:27 von alopex -
Hi,
danke für deine Antwort.
Das mit dem mb_strtolower() funktioniert, läuft super, danke.
Jetzt liegt nur noch das problem an ucwords(), da eine Funktion wie mb_ucwords() leider nicht existiert. Ich kann leider auch nichts bei den User-Beiträgen finden ... hättets du hier vielleicht noch ein Vorschlag?
Ich hab dies hier noch gefunden:
http://viewsvn.cmsmadesimple.org/viewsvn/branches/1.1/lib/phputf8/ucwords.php?rev=3622&sortby=author&view=markup
Jedoch läuft dies nicht richtig mit den russischen Wörtern.
EDIT:
Ich habs!
<?php function utf8_ucwords($str) { $pattern = '/(^|([\x0c\x09\x0b\x0a\x0d\x20]+))([^\x0c\x09\x0b\x0a\x0d\x20]{1})[^\x0c\x09\x0b\x0a\x0d\x20]*/u'; return preg_replace_callback($pattern, 'utf8_ucwords_callback',$str); } function utf8_ucwords_callback($matches) { $leadingws = $matches[2]; $ucfirst = mb_strtoupper($matches[3],mb_detect_encoding($matches[3])); $ucword = utf8_substr_replace(ltrim($matches[0]),$ucfirst,0,1); return $leadingws . $ucword; } function utf8_substr_replace($str, $repl, $start , $length = NULL ) { preg_match_all('/./us', $str, $ar); preg_match_all('/./us', $repl, $rar); if( $length === NULL ) { $length = utf8_strlen($str); } array_splice( $ar[0], $start, $length, $rar[0] ); return join('',$ar[0]); } ?>
mfg,
hr
Beitrag geändert: 30.6.2007 14:38:54 von heavyraptor -
Könnte mb_convert_case() mit dem Parameter MB_TITLE dir weiterhelfen?
http://de.php.net/manual/de/function.mb-convert-case.php
-
Könnte mb_convert_case() mit dem Parameter MB_TITLE dir weiterhelfen?
http://de.php.net/manual/de/function.mb-convert-case.php
Hi,
Dies sieht auch ganz interessant aus, danke.
Ich habe jedoch gerade bemerkt, dass mein online-Server keine Multibyte-Funktionen unterstützt ... jedoch funktioniert es mit Hilfe deiner Funktion foxy_utf8_to_nce() und mit dem, was ich gefunden habe (utf8_ucwords() usw).
Ich hab' folgenden Array um Grossbuchstaben zu Kleinbuchstaben bzw. verkehrt rum zu ersetzten:
<?php $UTF8_LOWER_TO_UPPER = array( 0x0061=>0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042, 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100, 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393, 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C, 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F, 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E, 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3, 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A, 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9, 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C, 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4, 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164, 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156, 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118, 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128, 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428, 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055, 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A, 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC, 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0, 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D, 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0, 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5, 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA, 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045, 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F, 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048, 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6, 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407, 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395, 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396, 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051, 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408, 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F, 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126, 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C, 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E, 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB, 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421, 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A, 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102, 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9, 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122, ); ?>
Deine Funktion foxy_utf8_to_nce() hab' ich so umgebaut, dass ein Array mit den Zeichencodes zurückgegeben wird. Dann kann ich mit einer weiteren Funktion die Zeichen ersetzen.
Als Ersatz von ucwords() verwende ich die vorhin gepostete Funktion (mit Hilfe von einem RegEx), was auch richtig klappt, jedoch hab' ich den RegEx noch etwas verbessert.
Danke nochmals :).
mfg,
hr -
Hmm tät mich wundern wenn das alle Entsprechungen in deinem $UTF8_LOWER_TO_UPPER Array wären, aber könnte durchaus sein.
Die Funktion mb_strtolower() dürfte es auf jedenfall auch tun, sonst wäre es ja keine Multibyte Funktion geworden
Grüßle
Beitrag geändert: 2.7.2007 19:40:15 von scout -
Ich habe jedoch gerade bemerkt, dass mein online-Server keine Multibyte-Funktionen unterstützt ... jedoch funktioniert es mit Hilfe deiner Funktion foxy_utf8_to_nce() und mit dem, was ich gefunden habe (utf8_ucwords() usw).
Ich hab' folgenden Array um Grossbuchstaben zu Kleinbuchstaben bzw. verkehrt rum zu ersetzten:
...
Deine Funktion foxy_utf8_to_nce() hab' ich so umgebaut, dass ein Array mit den Zeichencodes zurückgegeben wird. Dann kann ich mit einer weiteren Funktion die Zeichen ersetzen.
Als Ersatz von ucwords() verwende ich die vorhin gepostete Funktion (mit Hilfe von einem RegEx), was auch richtig klappt, jedoch hab' ich den RegEx noch etwas verbessert.
Danke nochmals :).
Jaja, bau nur alles um!
Ich hatte am Wochenende selbst zwei Funktionen gebastelt, die Unicode-Buchstaben jeweils größer oder kleiner machen können (Title-Case muss ich mir erst noch genauer anschauen). Die decken 436 Buchstabenpaare (jeweils groß+klein) ab, "Nicht-Buchstaben" werden ignoriert. Die Tabellen dazu hab ich mit der Hilfe von charmap.exe gebastelt. Lustig, dass es mindestens 3 verschiedene Anordnungen gibt, wie Klein- auf Großbuchstaben folgen. Dabei sollte Unicode doch alles einfacher machen ...
/// builds an array for UCS case conversion function _ucs_case_conversion_table( $to_lower = 1 /// -1 if conversion goes from lower to upper case ) { $table = array ( //1st char, last char, offset 0x41 => array (0x5a, 0x20), // lat ASCII 0xc0 => array (0xd6, 0x20), // lat ISO-8859-1 (non-ASCII) 0xd8 => array (0xde, 0x20), // dito 0x100 => array (0x136, 1), // eastern european 1 0x139 => array (0x147, 1), // eastern european 2 // hier sind Großbuchstaben ungerade 0x14a => array (0x176, 1), // eastern european 3 0x179 => array (0x17d, 1), // eastern european 4 // hier Großbuchstaben ungerade 0x1a0 => array (0x1a2, 1), // eastern european 5 0x1a7 => array (0x1a7, 1), // eastern european 6 0x1af => array (0x1af, 1), // eastern european 7// ungerade 0x1b3 => array (0x1b5, 1), // eastern european 8 // ungerade 0x1cd => array (0x1db, 1), // eastern european 9 // ungerade 0x1de => array (0x1ee, 1), // eastern european 10 0x1f1 => array (0x1f1, 2), // eastern european 10 0x1f4 => array (0x1f4, 1), // eastern european 10 0x1f8 => array (0x1fe, 1), // eastern european 11 0x386 => array (0x386, 0x26), // greek alpha + (+U384) tonzeichen 0x388 => array (0x38a, 0x25), // greek epsilon,eta,iota + (+U384) tonzeichen 0x38c => array (0x38c, 0x40), // greek omicron + (+U384) tonzeichen 0x38e => array (0x38f, 0x3f), // greek ypsilon, omega ; + (+U384) tonzeichen //0x390 => array (0x390, 0), // greek iota + (+U384) tonzeichen + () diärese // there is no corresponding uc letter in charmap.exe 0x391 => array (0x3a1, 0x20), // greek //0x3a2 => array (0x3a2, 0), // greek: sigma lc endform 0x3a3 => array (0x3ab, 0x20), // greek 0x3da => array (0x3e0, 1), // greek: stigma, digamma, koppa, sampi 0x3e2 => array (0x3ec, 1), // coptic 0x401 => array (0x40f, 0x50), // cyrillic 2 0x410 => array (0x42f, 0x20), // cyrillic 1 0x462 => array (0x480, 1), // cyrillic 3 0x488 => array (0x4be, 1), // cyrillic 3 0x4d0 => array (0x4f8, 1), // cyrillic 4 0x1e80 => array (0x1e94, 1), // latin (mit Zusatzzeichen) //0x1e96 => array (0x1e9e, 1), // latin (mit Zusatzzeichen) 0x1ea0 => array (0x1ef8, 1), // latin (mit Zusatzzeichen) 0x1f08 => array (0x1f0f, -8), // greek: alpha 0x1f18 => array (0x1f1d, -8), // greek: epsilon 0x1f28 => array (0x1f2f, -8), // greek: eta 0x1f38 => array (0x1f3f, -8), // greek: iota 0x1f48 => array (0x1f4d, -8), // greek: omikron 0x1f59 => array (0x1f59, -8), // greek: ypsilon 0x1f5b => array (0x1f5b, -8), // greek: ypsilon 0x1f5d => array (0x1f5d, -8), // greek: ypsilon 0x1f5f => array (0x1f5f, -8), // greek: ypsilon 0x1f68 => array (0x1f6f, -8), // greek: omega 0x1f88 => array (0x1f8f, -8), // greek: alpha 0x1f98 => array (0x1f9f, -8), // greek: eta 0x1fa8 => array (0x1fAf, -8), // greek: omega 0x1fb8 => array (0x1fbc, -8), // greek: alpha 0xfffd => array (0xfffd, 0) // Ersatzzeichen fuer unbekannte Kodierungen <? > ); ksort($table); if ($to_lower >= 1) return $table; $rev_table = array (); foreach ($table as $start => $val) { //if (($start + $val[1]) > ) printf('<br />'); $rev_table[$start + $val[1]] = array ( $val[0] + $val[1], $val[1] ); } ksort($rev_table); return $rev_table; } /// converts a given UCS value to UCS value of the corresponding lower case letter function ucs_to_lower( $ucs_val = 0 /// integer ) { static $table; if (empty($table)) $table = _ucs_case_conversion_table(1); foreach ($table as $start => $val) { if ($ucs_val < $start) break; if ($ucs_val > $val[0]) continue; if (1 == $val[1]) { if ((1 & $ucs_val) && !(1 & $start)) break; // is already lower case } $lc_val = $ucs_val + $val[1]; } if (isset($lc_val)) return $lc_val; return $ucs_val; } /// converts a given UCS value to UCS value of the corresponding upper case letter function ucs_to_upper( $ucs_val = 0 /// integer ) { static $table; if (empty($table)) $table = _ucs_case_conversion_table(-1); foreach ($table as $start => $val) { if ($ucs_val < $start) break; if ($ucs_val > $val[0]) continue; if (1 == $val[1]) { if (!(1 & $ucs_val) && (1 & $start)) break; // already upper case } $uc_val = $ucs_val - $val[1]; } if (isset($uc_val)) return $uc_val; return $ucs_val; }
Das waren die "Hilfsfunktionen". Jetzt kommen die zwei Funktionen, die ganze Strings größer- oder kleinermachen können:
/// converts ASCII including HTML's NCRs function str_to_upper( $string = EMPTY_STRING ) { return preg_replace_callback( '/(&#(\d+);|[\x61-\x7a]([\xc0-\xff]))/', create_function( '$matches', 'if (empty($matches[2])) { if (empty($matches[3])) return strtoupper($matches[1]); return \'&#\'.ucs_to_upper(ord($matches[1])).\';\'; } return \'&#\'.ucs_to_upper($matches[2]).\';\';' ), $string ); } /// converts ASCII including HTML's NCRs function str_to_lower( $string = EMPTY_STRING ) { return preg_replace_callback( '/(&#(\d+);|[\x41-\x5a]|([\xc0-\xff]))/', create_function( '$matches', 'if (empty($matches[2])) { if (empty($matches[3])) return strtolower($matches[1]); return \'&#\'.ucs_to_lower(ord($matches[1])).\';\'; } return \'&#\'.ucs_to_lower($matches[2]).\';\';' ), $string ); }
Prinzipiell liese sich das auch direkt auf UTF8 abbilden, aber ich hatte bisher keine Lust das zu machen und auch keine Verwendung dafür ...
Übrigens sind nur zwei Zwinkersmileys in diesem Post von mir. Die anderen (im Quelltext) hat das Lima-Board zu verantworten ...
... und ich entschuldige mich schon mal dafür, dass ich die Layout-Grenzen gesprengt habe (mit den create_function()-Zeilen) ...
Beitrag geändert: 5.7.2007 18:29:08 von alopex -
Hi,
dine Funktionen sehen interessant aus ... meine Funktionen funktionieren zwar, aber mal sehen, vielleicht erweitere ich diese noch mit deinem Code.
Was ich jedoch nicht ganz verstehe ist dein Array zur Gross- und Kleinbuchstaben-Umwandlung. Werden da wirklich alle Zeichen behandelt?
mfg,
hr -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage