簡體   English   中英

php的mb_detect_encoding()

[英]php's mb_detect_encoding()

首先,我想說我已經閱讀了另一篇關於php的mb_detect_encoding的帖子,這篇文章是關於PHP 中mb_detect_order()的奇怪行為 這肯定再確認我通過追蹤和錯誤學到了什么。 但是仍有一些事情讓我感到困惑。

我正在構建一個主要是英文網站的html抓取工具,它們收集數據並將其存儲為UTF-8 XML。 我遇到了一個頁面自我聲明ISO-8859-1字符集的問題,但它包含Windows-1252獨有的字符。 特別是正確的單引號(')0x92。 據我了解,windows-1252是iso-8859-1的超集,它促使我思考為什么要使用utf8_encode()呢? 為什么不使用iconv('Windows-1252','UTF-8',$ str)代替utf8_encode(),因為iso-8859-1中表示的任何內容都會被轉換為windows-1252獨有的字符(即。€,ƒ''“”)

$ansi = "€";//euro mark, the code file itself is in ansi

$detected = mb_detect_encoding($ansi, "WINDOWS-1252");// $detected == "Windows-1252"
$detected = mb_detect_encoding('a'.$ansi, "WINDOWS-1252");// $detected == FALSE
$detected = mb_detect_encoding($ansi.'a', "WINDOWS-1252");// $detected == "Windows-1252"
$detected = mb_detect_encoding($ansi.'a', "WINDOWS-1252",TRUE);// $detected == FALSE

為什么會這樣? 如果字符串中的第一個字符不是windows-1252,即使其余部分是,它也會失敗? 這種行為不會使它變得毫無用處嗎? 至於區分iso-8859-1和windows-1252

另一件令我困惑的事情是,我想要檢測ASCII,ISO-8859-1,windows-1252,UTF-8之間的字符集。 是否有可能以一種給我排名最低的方式檢測字符串? (即。

$ascii = "123"; // desired detect result == 'ASCII'
$iso = "é".$ascii; // desired detect result == 'ISO-8859-1'
$ansi = "€".$iso; // desired detect result == 'Windows-1252'
$utf8 = file_get_contents('utf8.txt', true);//$utf8 == '你好123é€', desired detect result == 'UTF-8'

不應該是$ detect_order = array('ASCII','ISO-8859-1','Windows-1252','UTF-8'); 我知道這是不正確的,因為它給了我以下結果

$ascii == 'ASCII'
$iso   == 'ISO-8859-1'
$ansi  == 'ISO-8859-1'
$utf8  == 'ISO-8859-1'

為什么我的檢測順序('ASCII','ISO-8859-1','Windows-1252','UTF-8')錯誤的我想得到什么?

我得到的最接近的期望回報值是

$ascii == 'ASCII'
$iso   == 'ISO-8859-1'
$ansi  == 'ISO-8859-1'
$utf8  == 'UTF-8'

以下兩個mb_detect_order數組都給了我上面的值

$detect_order = array('ASCII', 'UTF-8', 'Windows-1252', 'ISO-8859-1');
$detect_order = array('ASCII', 'UTF-8', 'ISO-8859-1', 'Windows-1252');

這讓我感到困惑!

嗯,有人可以對此有所了解嗎? 非常感謝!

這是一個已知的錯誤

只有當整個字符串由特定范圍內的高字節字符組成時, Windows-1251Windows-1252才會成功。 這意味着你永遠無法獲得正確的轉換,因為即使是Windows-1252 ,文本也會顯示為ISO-8859-1

我遇到了從LATIN1轉換為UTF-8 我有許多內容從Microsoft Word粘貼並使用MySQL表的LATIN1字符集存儲在VARCHAR字段中。 你可能知道Word將撇號和引號轉換為智能撇號和引號。 它們都不會顯示在屏幕上,因為這些字符未正確轉換。 該文本始終標識為ISO-8859-1 為了解決這個問題,我強制從Windows-1252轉換為UTF-8並且撇號和引號(以及其他字符)都被正確轉換。

不確定我是否會回答你的所有問題,但我們在這里:

據我了解,windows-1252是iso-8859-1的超集,它促使我思考為什么要使用utf8_encode()呢? 為什么不使用iconv('Windows-1252','UTF-8',$ str)代替utf8_encode(),因為iso-8859-1中表示的任何內容都將被轉換為windows-1252獨有的字符

你不應該打擾ut8_encode。 轉到iconv()或mb_convert_encoding。 ut8_encode僅將ISO-8859-1轉換為UTF-8。 如果你需要在不同的編碼之間進行轉換,你應該使用其他功能。

關於歐元馬克。 不確定是否在某些時候(正式或非正式)添加到ISO-8859-1但下面的聲明都返回true

$ansi = "€";//euro mark, the code file itself is in ansi

$detected = mb_detect_encoding($ansi, "WINDOWS-1252", TRUE);// $detected == "Windows-1252"
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "ISO-8859-1", TRUE);// $detected == ISO-8859-1
echo $detected."<br/>-<br/>";


$detected = mb_detect_encoding($ansi, "WINDOWS-1252");// $detected == "Windows-1252"
echo $detected."<br/>-<br/>";
$detected = mb_detect_encoding($ansi, "ISO-8859-1");// $detected == ISO-8859-1
echo $detected."<br/>-<br/>";

注意,這是嚴格設置為True或False的結果。 這可能解釋了原因

不應該是$ detect_order = array('ASCII','ISO-8859-1','Windows-1252','UTF-8'); 我知道這是不正確的,因為它給了我以下結果

給你ISO-8859-1。 我注意到你在后一個順序中切換了UTF-8,領先於ISO,這就是為什么它最終給了你UTF-8。

為什么我的檢測順序('ASCII','ISO-8859-1','Windows-1252','UTF-8')錯誤的我想得到什么?

根據php的網站http://us3.php.net/manual/en/function.mb-detect-order.php ,在UTF-8之前設置ISO將始終返回ISO。 檢查他們的無用檢測順序示例。

從我所看到的情況來看,似乎如果你同時擁有ISO-8859-1和Windows-1252,你將獲得ISO。 如果你拿出一個或另一個,你將得到兩個剩下的東西。 所以下面最后2個的位置似乎沒有什么區別

$ detect_order = array('ASCII','UTF-8','Windows-1252','ISO-8859-1'); $ detect_order = array('ASCII','UTF-8','ISO-8859-1','Windows-1252');

€符號不是utf8編碼的一部分!

你必須把它作為€!

或編碼到windows-1252或iso-8859-15(與iso-8859-1相同,但有符號)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM