字符编码转换的问题

发布于 2022-09-12 01:44:28 字数 1213 浏览 28 评论 0

公司从亚马逊上拉取日语数据下来,存到数据库,但是亚马逊可能给的是日语编码的,数据库格式是utf8的,存到数据库之后就乱码了:

Rampow iPhone儔僀僩僯儞僌働乕僽儖亂2M/Apple Mfi 擣徹/塱 媣曐徹亃 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo

我尝试用以下代码解决,但是转出来的内容还是乱码:

$str = 'Rampow iPhone儔僀僩僯儞僌働乕僽儖亂2M/Apple Mfi 擣徹/塱 媣曐徹亃 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo';  
  
$fileType = mb_detect_encoding($str, ["JIS", "eucjp-win", "SJIS-win"]);  
  
if( $fileType != 'UTF-8'){  
  $str = mb_convert_encoding($str ,'utf-8' , $fileType);  
}  
  
echo $str;

输出内容:

Rampow iPhone蜆泌ム蜒ゥ蜒ッ蜆槫レ蜒堺ケ募?蜆紋コ?M/Apple Mfi 謫」蠕ケ/蝪ア 蟐」譖仙セケ莠 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo

我又尝试把源字符串,也就是Rampow iPhone儔僀僩僯儞僌働乕僽儖亂2M/Apple Mfi 擣徹/塱 媣曐徹亃 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo存在一个txt文本里,用Notepad++打开,结果一打开就显示了正常的日文:Rampow iPhoneライトニングケーブル【2MApple Mfi 認証永 久保証】 iPhone 1111 Pro11 Pro MaxXSXS MaxXRiPhone X89 PlusiPadiPo,并且发现编码格式是Shift-JIS

请教一下大佬,这种格式应该怎么转成utf8,并显示正常的日文呢?


贴一下数据库内容,可以看到都是乱码的:
image.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅浅 2022-09-19 01:44:28

来更新一下,最后算是解决了吧。源头已解决,剩下就是已经乱码的数据的转换。

因为看到notepad++可以让乱码可以还原成正常的日语,所以觉得还是有迹可循的。解决方式如下:

数据库中导出相关的数据,并且拼接成sql更新语句,例如:

SELECT
    CONCAT(
        "update `ve_market_refund` SET product_name='",
        product_name,
        "',customer_comments='",
        customer_comments,
        "' WHERE id=",
        id,
        ";"
    )
FROM
    `ve_market_refund`
WHERE
    account_finance_code IN (
        'Rampow-JP',
        'iVANKY-JP',
        'ATEVON-JP',
        'RAMPOWDIRECT-JP'
    );

然后把获取到的结果集,复制到txt文本里,另存为ANSI编码:

update `ve_amazon_all_orders` SET product_name='Rampow Micro USB 働乕僽儖亂1M/2杮慻/曐徹晅偒/崟亃 2.4A媫懍廩揹働乕僽儖 崅懍僨乕僞揮憲 7000+夞偺嬋愜僥僗僩 崅懴媣', promotion_ids='VPC-6-3149914 Coupon', ship_state='恄撧愳導', ship_city='' WHERE id=4460879;

然后把文件改成html后缀,浏览器打开,可以看到正常的日文数据:

update `ve_amazon_all_orders` SET product_name='Rampow USB Type C ケーブル【1m/黒/永 久保証付き】急速充電 QuickCharge3.0対応 USB3.0規格 usb-c タイプc ケーブル Sony Xperia', promotion_ids='VPC-6-3696972 Coupon', ship_state='埼玉県', ship_city='' WHERE id=11448470;

然后复制浏览器里的sql语句,再次新建一个txt文件放进去,ctrl+s保存的时候,会提示需要保存到unicode编码,然后保存成unicode编码,这时候文件成了utf16格式,再次重复将utf16转换成utf8,就可以了。

然后这么大量的sql语句,可以形成一个文件,通过命令行执行

mysql -u root -p < /usr/local/src/sql/refund_utf-8.sql

以上就是本次问题的解决方式,在找不到通过代码解决的时候,不妨一试。

梦里人 2022-09-19 01:44:28

$result为我从亚马逊MWS报告拉取的csv格式的字符串

# 检测编码,未检测到用市场指定的编码转utf8;检测出来,用检测的编码转utf8;如果是utf8,则不作处理
$encode = mb_detect_encoding($result, array("UTF-8",'iso-8859-1',"Shift_JIS","cp1252",'UTF-16')); 
                
if($encode == false){
    $marketplaceId = $this->config['Marketplace_Id'];
    if(in_array($marketplaceId, $this->market_EU) || in_array($marketplaceId, $this->market_US)){
        $result = mb_convert_encoding($result, "UTF-8", ["iso-8859-1", "cp1252"]);
    }else if(in_array($marketplaceId, $this->market_JP)){
        $result = mb_convert_encoding($result, 'UTF-8', ["Shift_JIS"]);
    }else if(in_array($marketplaceId, $this->market_CN)){
        $result = mb_convert_encoding($result, 'UTF-8', ["UTF-8", "UTF-16"]);
    }else{
        $result = mb_convert_encoding($result, "UTF-8", ["cp1252"]);
    }
}else if($encode != 'UTF-8'){
    $result = mb_convert_encoding($result, "UTF-8", $encode);
}

实际上出现了检测出编码为ISO-8859-1,最后转码还是乱码。该$result写入xls文件,双击打开日文显示正常。

后面发现,我改变该检测字符编码函数的第三个参数,结果却各不相同:
$encode = mb_detect_encoding($result, array("UTF-8",'iso-8859-1',"Shift_JIS","cp1252",'UTF-16'));

$encode = mb_detect_encoding($result, array("UTF-8",'Shift_JIS',"iso-8859-1","cp1252",'UTF-16'));

$encode = mb_detect_encoding($result);

同一个字符串三个返回结果都不一样。分别为:
ISO-8859-1
SJIS
false
这个检测编码的函数可能存在问题,需要后续深入研究。

但是,第二和第三的结果分别会构成
$result = mb_convert_encoding($result, 'UTF-8', 'SJIS');

$result = mb_convert_encoding($result, 'UTF-8', 'Shift_JIS');
逻辑。
都会正常转换成日文。

我的猜想是:
mb_convert_encoding并不是一个严格函数,在第三个参数【待检测的字符编码列表】给出的情况下,他会按顺序检测字符特性的符合度,达不到,按给出列表的顺序逐个匹配,达到一定符合度就直接返回匹配的编码,后续不再检测。
所以,在一个字符串的字符特性与多个编码的匹配度满足符合度的情况下,谁排在前面就return谁。所以出现了第一和第二的不同编码返回。

所以我这里建议是,如果已知目标字符串是哪国编码,指定转换即可,或者在mb_detect_encoding的检测列表将该国编码或者可能性按大小依次排列

对于你这个问题,既然已知日文,直接mb_convert_encoding($result, 'UTF-8', 'Shift_JIS');试试。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文