Php string detect encoding

Определение кодировки текста в PHP вместо mb_detect_encoding

Иногда появляется необходимость определить кодировку текста. И в PHP даже функция для этого есть:

Прочитав статьи m00t я не вдохновился его методом и нашел вот такое решение: Определение кодировки текста в PHP и Python
Как сказал m00t

Я протестировал функцию определения кодировки по кодам символов, результат меня удовлетворил и я использовал эту функцию пару лет.

Недавно решил переписать проект где использовал эту функцию, нашел готовый пакет на packagist.org cnpait/detect_encoding, в котором кодировка определяется методом m00t

При этом указанный пакет был установлен более 1200 раз, значит не у меня одного периодически возникает задача определения кодировки текста.

Мне бы установить этот пакет и успокоиться, но я решил «заморочиться».

В общем, сделал свой пакет: onnov/detect-encoding.

Как его использовать написано в README.md

А о его тестировании и сравнении с пакетом cnpait/detect_encoding напишу.

Методика тестирования

Берем большой текст: Tolstoy — Anna Karenina
Всего — 1’701’480 знаков

Убираем все лишнее, оставляем только кириллицу:

$text = preg_replace('/[^а-яА-Я]/ui', '', $text);

Осталось 1’336’252 кирилистических знаков.

В цикле берем часть текста (5, 15, 30,… символов) преобразуем в известную кодировку и пытаемся определить кодировку скриптом. Затем сравниваем правильно или нет.

Вот таблица в которой слева кодировки, сверху количество символов по которому определяем кодировку, в таблице результат достоверности в %%

letters -> 5 15 30 60 120 180 270
windows-1251 99.13 98.83 98.54 99.04 99.73 99.93 100.0
koi8-r 99.89 99.98 100.0 100.0 100.0 100.0 100.0
iso-8859-5 81.79 99.27 99.98 100.0 100.0 100.0 100.0
ibm866 99.81 99.99 100.0 100.0 100.0 100.0 100.0
mac-cyrillic 12.79 47.49 73.48 92.15 99.30 99.94 100.0

Наихудшая точность с мак-кириллицей, вам нужно как минимум 60 символов, чтобы определить эту кодировку с точностью 92,15%. Кодировка Windows-1251 также имеет очень низкую точность. Это связано с тем, что номера их символов в таблицах сильно пересекаются.

Читайте также:  Как создать file php

К счастью, кодировки mac-cyrillic и ibm866 не используются для кодирования веб-страниц.

letters -> 5 10 15 30 60
windows-1251 99.40 99.69 99.86 99.97 100.0
koi8-r 99.89 99.98 99.98 100.0 100.0
iso-8859-5 81.79 96.41 99.27 99.98 100.0

Точность определения высока даже в коротких предложениях от 5 до 10 букв. А для фраз из 60 букв точность определения достигает 100%. А еще, определение кодировки выполняется очень быстро, например, текст длиной более 1 300 000 символов кириллицы проверяется за 0.00096 секунд. (на моем компьютере)

А какие результаты покажет статистический способ описанный m00t:

letters -> 5 10 15 30 60
windows-1251 88.75 96.62 98.43 99.90 100.0
koi8-r 85.15 95.71 97.96 99.91 100.0
iso-8859-5 88.60 96.77 98.58 99.93 100.0

Как видим результаты определения кодировки хорошие. Скорость работы скрипта высокая, особенно на коротких текстах, на огромных текстах скорость значительно уступает. Текст длиной более 1 300 000 символов кириллицы проверяется за 0.32 секунд. (на моем компьютере).

Мои выводы

  • Обе методики дают хорошие результаты.
  • Точность методов близка.
  • Скорость определения по кодам символов выше на больших текстах, но вряд ли это имеет большое значение, т.к. мало вероятно, что кто то будет проверять такие огромные тексты.
  • У статистического метода еще есть потенциал для увеличения точности определения кодировок.

Источник

PHP – How to detect character encoding using mb_detect_encoding()

In PHP, mb_detect_encoding() is used to detect the character encoding. It can detect the character encoding for a string from an ordered list of candidates. This function is supported in PHP 4.0.6 or higher version.

mb_detect_encoding() is useful with multibyte encoding, where not all sequences of bytes form a valid string. If the input string contains such type of a sequence, then that encoding will be rejected, and it will check for the next encoding.

Syntax

string mb_detect_encoding(str $string, str $encoding, bool $strcit)

Automatic detection of character encoding is not entirely reliable without some additional information. We can say that character encoding detection is similar to decoding an encrypted string without the key. A content-Type HTTP header can be used for an indication of character encoding stored or transmitted with the data.

Читайте также:  Простые методы сортировки java

Parameters

The mb_detect_encoding function accepts three parameters −

  • $string − This parameter is used for the string being examined.
  • $encoding − This parameter is used for a list of character encoding to try in order. The list may be specified in any format like an array of strings or only a single string separated by commas. In case the encoding is omitted or null, then the current detect_order is set with the mbstring.detect_order configuration option or mb_detect_order() function will be used.
  • $strict − this parameter is used to control the behavior when the string is not valid in any of the listed encodings. If the strict is set to false, then it will return the closest matching encoding. If the strict is set to true, it will return false.

Return Values

It returns the detected character encoding, or it returns False if the string is not valid in any of the listed encoding.

Example 1

mb_detect_encoding() function without strict parameter

Output

Example 2

mb_detect_encoding() function using strict parameter.

Output

string(5) "UTF-8" bool(false) string(10) "ISO-8859-1" string(10) "ISO-8859-1"

Источник

mb_detect_encoding

Detects the most likely character encoding for string string from an ordered list of candidates.

Automatic detection of the intended character encoding can never be entirely reliable; without some additional information, it is similar to decoding an encrypted string without the key. It is always preferable to use an indication of character encoding stored or transmitted with the data, such as a «Content-Type» HTTP header.

This function is most useful with multibyte encodings, where not all sequences of bytes form a valid string. If the input string contains such a sequence, that encoding will be rejected, and the next encoding checked.

Parameters

The string being inspected.

A list of character encodings to try, in order. The list may be specified as an array of strings, or a single string separated by commas.

If encodings is omitted or null , the current detect_order (set with the mbstring.detect_order configuration option, or mb_detect_order function) will be used.

Читайте также:  Html code color code chart

Controls the behaviour when string is not valid in any of the listed encodings . If strict is set to false , the closest matching encoding will be returned; if strict is set to true , false will be returned.

The default value for strict can be set with the mbstring.strict_detection configuration option.

Return Values

The detected character encoding, or false if the string is not valid in any of the listed encodings.

Источник

Как определить кодировку строки на PHP?

При парсинге сайта необходимо определить кодировку.. известно что mb_detect_encoding() работает не правильно, по метатегам определять не вариант, есть вообще реализация на PHP для определения кодировок?

OKrasnov

Я видел это решение, слишком мудреное. На самом мне нужно определить кодировку страницы а не строки, вопрос поставленный мной вначале слмшком идеален. Я изобрел свой как оказалось велосипед. Я так подумал..Ведь сервер отдает заголовки с кодировкой, и их прочитать можно и это не то что верстальщику надумалось вписать в метатег. И заголовок важнее чем мета. Впрочем. получив заголовок сервера можно поискать и в метатеге. Прокомментируйте плс мое решение. где здесь могут быть подводные камни?

Как я понял Вы про curl и страницу которую парсим. Попробуй вот это, тут перекодировка в utf8, нужные куски выдрать тебе думаю будет не проблема

@author * @copyright 2014 */ function curl_exec_utf8($ch) < $data = curl_exec($ch); if (!is_string($data)) return $data; unset($charset); $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); /* 1: HTTP Content-Type: header */ preg_match( '@([\w/+]+)(;\s*charset=(\S+))?@i', $content_type, $matches ); if ( isset( $matches[3] ) ) $charset = $matches[3]; /* 2: element in the page */ if (!isset($charset)) < preg_match( '@/* 3: element in the page */ if (!isset($charset)) < preg_match( '@/* 4: PHP's heuristic detection */ if (!isset($charset)) < $encoding = mb_detect_encoding($data); if ($encoding) $charset = $encoding; >/* 5: Default for HTML */ if (!isset($charset)) < if (strstr($content_type, "text/html") === 0) $charset = "ISO 8859-1"; >/* Convert it if it is anything but UTF-8 */ /* You can change "UTF-8" to "UTF-8//IGNORE" to ignore conversion errors and still output something reasonable */ if (isset($charset) && strtoupper($charset) != "UTF-8") $data = iconv($charset, 'UTF-8', $data); return $data; > ?>

Источник

Оцените статью