php使用正则表达式和翻译字典json文件做翻译

需求:把页面中的中文翻译成越南文。

思路:在框架渲染页面的地方(这个地方能获取到页面渲染后的所有html数据,设为$str),使用以下方法。

php 复制代码
//翻译中文 读取json文件,使用正则表达式替换中文
public static function pregReplaceChinese($str,,$toLanguageType = 'vietnam',$isNotHtml = false){
    if(empty($str)){
        return $str;
    } else {
        //翻译字典json文件 例子
        //$jsonFile ='{
        //  "追风剑": "Truy Phong Kiếm",
        //  "追风镯": "Truy Phong Trạc"
        //}';

        //0、翻译前准备 正则关键字符数组,避免影响到后面正则替换翻译
        $regexChars = ['^', '$', '.', '|', '?', '*', '+', '(', ')', '[', ']', '/', '-'];
        $unicodeChars = ['%u005e','%u0024','%u002e','%u007c','%u003f','%u002a','%u002b','%u0028','%u0029','%u005b','%u005d','%u002f','%u002d'];
        $oldContent = $str;

        //1、获取翻译关键字的json文件,将其转换为数组
        $jsonFile = 'http://admin.vanmac.zagoo.vn/language/vietnam.json';
        $fyChars = file_get_contents($jsonFile);
        $jsonArr = json_decode(str_replace($regexChars,$unicodeChars,$fyChars), true);//翻译json文件转换为数组
        if (is_string($str)) {
            $str = str_replace($regexChars,$unicodeChars,$str);//正则关键字符替换
        }


        //1-1、非页面翻译
        if ($isNotHtml) {
            // 处理数组(如道具数组)翻译
            if (is_array($str)) {
                $jsonArr = json_decode($fyChars, true);//翻译json文件转换为数组
                foreach($str as $key => $item){
                    if (!empty($jsonArr[$item['name']])) {
                        $str[$key]['name'] = $jsonArr[$item['name']];
                    }
                }
                return $str;
            }


            // 处理Excel表格内容和表格文件名称翻译
            if (strpos($str,'交易ID') !== false || strpos($str,',') !== false) {
                $str = iconv('gbk', 'utf-8', $str);
                if (strpos($str,'交易ID') !== false) { $str = str_replace('交易ID','交易id',$str); }
                $arr[0] = explode(',',$str);
            }
            if (empty($arr[0])) { preg_match_all('/[\x{4e00}-\x{9fa5}]+/u', $str, $arr); }

        } else {
            //2、获取页面中的>任意内容<,将其转换为数组
            $pattern = '/>[\s\S]*?<|title="([^"]+)"|value="([^"]+)"/';
            preg_match_all($pattern, $str, $arr);
        }



        //3、使用正则表达式preg_replace翻译替换中文处理,需要生成的两个关联数组,且索引保持一致才能进行顺序替换,其中匹配翻译的数组,当没有找到翻译关键字则设置为当前关键字
        $patterns = [];//需要翻译的数组
        $replaces = [];//匹配翻译的数组
        foreach($arr[0] as $item){
            $itemArr = [];
            $item = trim(str_replace(['>','<','title=','value='],'',$item));
            if(empty($item) || strstr($item, "u005d%u002e") || strstr($item, "'u005d'") || strstr($item, "'%u0029;")|| strstr($item, "}%u0029;") || strstr($item, "html") || strstr($item, "function ") || strstr($item, "label {") || strstr($item, "+json") || strstr($item, "%u002a")){//可能是页面代码如html、js/css代码
                continue;
            }
            $item = trim($item, '"');
            if (strpos($item,' 数量:') !== false) {//邮件列表道具翻译特殊处理
                 $itArr = explode('%u002e',$item);// %u002e--|
                 foreach ($itArr as $it1) {
                     $it1Arr = array_filter(explode(' ',$it1));
                     foreach ($it1Arr as $it2) {
                         $it2Arr = array_filter(explode(':',$it2));
                         foreach ($it2Arr as $it3) {
                             if (strpos($it3,'数量') !== false) { $it3 = ' '.$it3.':'; }
                             if (strpos($it3,'物品') !== false) {
                                 if (strpos($it3,'充值额度%u0029') !== false) {//例 (不增加充值额度)物品
                                     $it4Arr = explode('%u0029',$it3);
                                     $itemArr[] = $it4Arr[0].'%u0029';
                                     $itemArr[] = $it4Arr[1].':';
                                     continue;
                                 } else {
                                     $it3 = $it3.':';
                                 }
                             }
                             $itemArr[] = $it3;
                         }
                     }
                 }
            }
            if (strstr($item, " 总充值")) {//处理个别翻译
                $itemArr[] = '总充值';
            }

            if (!isset($itemArr[$item])) {
                $itemArr[$item] = $item;
            }

            foreach ($itemArr as $item) {
                self::arrayAss($jsonArr,$patterns,$replaces,$item);
            }
        }
        //数组按照键值长度 倒叙排序
        uksort($patterns, function($a, $b) {
            return strlen($a) < strlen($b);
        });
        uksort($replaces, function($a, $b) {
            return strlen($a) < strlen($b);
        });

        $content = preg_replace($patterns, $replaces, $str);
        if(!empty($content)){
            $content = str_replace($unicodeChars,$regexChars,$content);
            if (strpos($content,'<|/|d|i|v|>|') !== false) {//有些页面经过转换后 出现多余|
                $content = str_replace('|','',$content);
            }
        } else {
            $content = $oldContent;
        }
        return $content;
    }
}


//拼接原字符串和翻译字符串的数组
public static function arrayAss($jsonArr,&$patterns,&$replaces,$item){
    $patterns[$item] = '/'.$item.'/';
    if (!empty($jsonArr[$item])) {
        $replaces[$item] = $jsonArr[$item];
    } else {
        $replaces[$item] = $item;
    }
}

调用方法

php 复制代码
//页面翻译
if (Tool::isvietnam()) {//翻译(用户点击了翻译按钮,Tool::isvietnam()方法是从缓存中获取用户是否点击了翻译按钮)
    $content = Tool::pregReplaceChinese($content);
}

//或者 Excel内容/文件名(纯中文)翻译
if (Tool::isvietnam()) {//翻译
    $filename = Tool::pregReplaceChinese($filename,'vietnam',true);//Excel文件名
    $data = Tool::pregReplaceChinese($data,'vietnam',true);//Excel内容字符串 交易ID,x,x,商品名称,x,x等
}
相关推荐
Venuslite1 小时前
从 Unexpected token < 到 Extra data:一次讲清 JSON 解析错误的排查思路
json
疯狂SQL6 天前
手写高性能在线 JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
typescript·json·next.js·web worker·前端性能优化·esbuild·源码实战
两个人的幸福7 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo9 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack9 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820710 天前
PHP 扩展——从入门到理解
php
鹏仔先生11 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下11 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip11 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
踏着七彩祥云的小丑11 天前
Go学习第9天:并发编程 + 文件操作 + 正则表达式
学习·golang·正则表达式·go