как определить что текст в utf-8 , и проблемы с конвертацией

-=SG=-

Guest
как определить что текст в utf-8 , и проблемы с конвертацией

Драсти уважаемые ...

в поиске инфы перекодировки с utf8 -> win наткнулся на эту тему http://phpclub.ru/talk/showthread.php?old=1&threadid=23121
Функция работает, однако на выходе получаем:
Маша мыла 53343Аму! А 53343ама не терялся...
т.е. гдето непрописана буква "р" а где исправить не догоняю, может подскажете, кто юзал?

-~{}~ 23.12.04 13:14:

зы mb_convert_encoding($str, "windows-1251", "UTF-8"); не пашет
 

-=SG=-

Guest
iconv тоже нет ..но проблема решена ... вот, если кому понадобится
PHP:
$fcontents = "РњР°С?Р° мыла Р_РђРјСѓ! Рђ Р_ама РЅРµ терялся...";
 $out = $c1 = ""; 
    $byte2=false; 
    for ($c=0;$c<strlen($fcontents);$c++){ 
      $i=ord($fcontents[$c]); 
      if ($i<=127) $out.=$fcontents[$c]; 
      if ($byte2){ 
        $new_c2=($c1&3)*64+($i&63); 
        $new_c1=($c1>>2)&5; 
        $new_i=$new_c1*256+$new_c2; 
        if ($new_i==1025){ 
          $out_i=168; 
        } 
        else{ 
          if ($new_i==1105){ 
            $out_i=184; 
          } 
          else { 
            $out_i=$new_i-848; 
          } 
        } 
      $out.=chr($out_i); 
      $byte2=false; 
      } 
      if (($i>>5)==6) { 
        $c1=$i; 
        $byte2=true; 
      } 
    } 
$fcontents=$out;
 

Фанат

oncle terrible
Команда форума
-=SG=-
этот код встречается на этом форуме уже раз 20. И те, кто умеют искать, его найдут и так. А те, м, кто не умеет, он, соответственно, не пригодится
а проблему определения ты уже решил?
 

-=SG=-

Guest
нет, вот тока обломался, mb_detect_encoding не пашет :( ... есть идеи?

выкрутился пока так:
if (stristr($fcontents,"ѓ") && stristr($fcontents,"°"))
но это есесно не дело...
 

SiMM

Новичок
PHP:
function is_ruUTF8($str){ // функция определяет "похожесть" строки на русскую UTF8 (C) SiMM
  return !preg_replace('#[\x00-\x7F]|\xD0[\x81\x90-\xBF]|\xD1[\x91\x80-\x8F]#s',
                       '',
                       $str
                      );
}
PHP:
function UTF8toCP1251($str){
  static $table = array("\xD0\x81" => "\xA8", // Ё
                        "\xD1\x91" => "\xB8", // ё
                       );
  return preg_replace('#([\xD0-\xD1])([\x80-\xBF])#se',
                      'isset($table["$0"]) ? $table["$0"] :
                       chr(ord("$2")+("$1" == "\xD0" ? 0x30 : 0x70))',
                      $str
                     );
}
PS: функцию is_ruUTF8 назвал более логично + избавился от неправильного определения строк вида \xD0\x34\x90 как русских
PPS: UTF8toCP1251 сделал более гибкой для поддержки языковых клонов CP1251
 

-=SG=-

Guest
скажем SiMM-у хором бААльшущий СЕНЬКС, в который раз выручает...
всем спасибо за участие...
 

lunux

Новичок
народ а можно что типа isWin показать, а то мне надо определить строка в кодировке windows 1251 или нет только енто. HELP! (конверторы которые я нашёл в форуме толи кривые толи не пашут с короткими строками, iconv и т.п. у меня на сервере не пашут
 

SiMM

Новичок
Автор оригинала: lunux
не пашут с короткими строками
Это невозможно. Потому и предложить кроме этого больше нечего, разве что ты расскажешь, откуда ты эти данные получаешь - возможно, найдётся другое решение.
 

Vasya

Guest
Автор оригинала: lunux
... надо определить строка в кодировке windows 1251 или нет ...
Делаю нонче вот так. Если символы в строке не из диапазона 1251, то пытаюсь отконверить их из utf8...
Если не получается, оставляю строку как есть.
PHP:
...
// try UTF-8
if(!isWin1251($string)) {
	$tmp = utf8win1251($string);
	if(isWin1251($tmp)) {
		$string = $tmp;
	}
}
...
function utf8win1251($s){
/// ... skipped ...
} // utf8win1251

function isWin1251($s) {
	if(preg_match("/^[\x20-\x7E\xA8\xB3\xB8\xC0-\xFF]*$/", $s)) {
		return true;
	}
	return false;
}
 

SiMM

Новичок
Автор оригинала: Vasya
PHP:
function isWin1251($s) {
	if(preg_match("/^[\x20-\x7E\xA8\xB3\xB8\xC0-\xFF]*$/", $s)) {
		return true;
	}
	return false;
}
Во-первых, не работает с многострочниками, во-вторых, дешевле возвращать false если найден хоть один инородный символ (return !preg_match('#[^\x00-\x7F\xA8\xB8\xC0-\xFF]#s',$s);), а в третьих, кроме CP1251 существуют ещё и другие кириллические кодировки - MacCyrillic, КОИ-8, ISO_8859-5, CP866, которые, в-третьих, пытается распознать код на страничке tony2001 - поэтому ваше решение, собственно, ничем не лучше. В любом случае, на коротких последовательностях вы так инчего не определите - пример - 'гиги' в UTF-8 (РіРіРіРі в CP1251) для вашего варианта окажется вполне валидным CP1251 ;)
 

Vasya

Guest
Автор оригинала: SiMM
Во-первых, не работает с многострочниками...
Да, тут я должен сказать, что решал задачу несколько более узкую... Область допустимых значений в ней уже... Это распознавание поисковых слов из рефереров с поисковиков.
1. Там практически нет многостроковых запросов
2. Примерно известно с какого поисковика какая кодировка может прийти
Для этой задачи моё решение вполне приемлемо для меня. И оно уж точно лучше, чем никакого... :) Возможно кому-то это так же будет полезно...
Кстати, очень хорошо работает на коротких последовательностях...
Но за критику, оптимизацию и ссылки спасибо!
 
Сверху