i18n国际化,半自动完成翻译并替换

812 阅读2分钟

在使用vue-i18n进行国际化切换时,我们需要把整个系统的或者当前页面所涉及到的中文字符进行翻译,并替换为i18n所执行的字符形式。本文主要目的就是快速,半自动对当前页面的进行翻译,生成中英文配置对象,并替换当前页面的所有中文。以下是实现步骤(不包含全部源码):

1、提取中文字符

let reg = /(?<!(\/\/|\*|\<\!\-\-).*)[a-zA-Z0-9()]*[\u4e00-\u9fa5]{2,}[a-zA-Z0-9(),:\u4e00-\u9fa5\-]*[\:\:\?\?!]?/g;
let allzh = input.match(reg) || [];

以上正则表达式,主要是排除相关注释内容,匹配出带有:、?等的中文语句。此表达式可能会有部分问题,使用时需根据实际所需进行修改优化。

2、翻译中文字符

本文翻译中文字符,使用的是免费的百度翻译api,可自行去官网申请并使用。

translate(str).then((item) => {
      let dst = item;
      let enArr = dst.split("_ ");
      for (let i = 0; i < enArr.length; i++) {
        let arr = enArr[i].toLowerCase().split(" ");
        arr = arr.map((item: string, index: number) => {
          if (index !== 0) {
            return item.replace(/^./g, item.charAt(0).toUpperCase());
          } else {
            return item;
          }
        });
        let resKey = arr
          .join("")
          .replace(":", "Col")
          .replace(/\(.*\)/g, "")
          .replace(/[,,!\!\-\?]/g, "");
        res[resKey] = arrParam[i];
      }
      resolve(res);
    });

翻译完之后,把翻译的字符串改成驼峰形式,并作为对象的key值,对象的value值为之前提取的中文字符串。

3、中文对象转换成英文对象

该步骤主要用于,对已经产生的中文配置对象进行转换,并生成value值为英文的对象。该步骤也可在第二部步中生成。

function zhObjToEn(obj: {
  [key: string]: string;
}): Promise<{ [key: string]: string }> {
  return new Promise((resolve, reject) => {
    let res = { ...obj };
    let tranStr = Object.values(obj).join("_");
    translate(tranStr).then((data) => {
      let enArr = data.split("_ ");
      Object.keys(res).forEach((item, index) => {
        res[item] = enArr[index];
      });
      resolve(res);
    });
  });
}

4、替换中文字符

根据生成的配置对象,对当前页面的符合标准的中文字符串进行全局替换。下面的正则表达式只包含了部分情况,具体写法可按照实际情况进行优化补充。

function toReplace(
  str: string,
  obj: { [key: string]: string },
  moduleName: string
): string {
  Object.entries(obj).forEach(([key, value]) => {
    // 不匹配注释内容 ,同时解决父串包含子串被子串替换的问题
    let reg = new RegExp(
      String.raw`(?<![\"\'\u4e00-\u9fa5]|(\/\/|\*).*)${value}(?!.*[\"\'\*\u4e00-\u9fa5])`,
      "g"
    );
    // 匹配 "" , ''内容
    let reg1 = new RegExp(String.raw`(?<!=)[\"\']${value}\?*[\"\']`, "g");
    str = str
      .replaceAll(`label="${value}"`, `:label="$t('${moduleName}.${key}')"`)
      .replaceAll(`title="${value}"`, `:title="$t('${moduleName}.${key}')"`)
      .replaceAll(
        `placeholder="${value}"`,
        `:placeholder="$t('${moduleName}.${key}')"`
      )
      .replaceAll(reg, `{{$t('${moduleName}.${key}')}}`);

    str = str.replaceAll(reg1, `this.$t('${moduleName}.${key}')`);
  });
  return str;
}

为方便操作,前期可以使用node.js中的fs模块,读取vue文件中的内容,并把替换完成的字符串写到新的文件(此处可能需要手动复制粘贴)。

基本的流程就是这些,有什么优化欢迎补充~。

后续会出现Vs Code插件版本,敬请期待!