将语言代码三个字符(ISO 639-2)转换为两个字符代码(ISO 639-1)

本文介绍了将语言代码三个字符(ISO 639-2)转换为两个字符代码(ISO 639-1)的处理方法,对大家解决问题具有一定的参考价值

问题描述

我正在开发一个使用文本到语音(TTS)引擎的Android应用程序。TTS组件以Locale对象列表的形式返回可用语言列表。

但每个Locale对象的Locale::getLanguageLocale::getISO3Language两个方法返回相同的3字符代码(ISO 639-2)。通常getLanguage()以2字符格式(ISO 639-1)返回语言代码,但对于特定设备,代码为3个字符。国家代码也是如此。但是,我需要两个字符格式的语言和国家代码(ISO 639-1)。

有人知道进行转换的方法吗?请注意,我需要一个具有两个字母格式的语言和国家/地区代码的相应Locale对象。

推荐答案

tl;dr

作为一种解决办法,请根据ISO 639-1将每个已知的Locale映射到其两个字母的语言代码。

new LocaleLookup().lookupTwoLetterLanguageCode( Locale.CANADA_FRENCH )

fr

或可能只分析Locale::toString的文本。

Locale
.CANADA_FRENCH      
.toString()         // fr_CA
.split( "_" )       // Array: { "fr" , "CA" }
[ 0 ]               // Grab first element in array, "fr". 

fr

对于两个字母的国家/地区代码,请使用拆分字符串的第二部分。使用1而不是0的索引。

Locale
.CANADA_FRENCH      
.toString()         // fr_CA
.split( "_" )       // Array: { "fr" , "CA" }
[ 1 ]               // Grab first element in array, "CA". 

CA

错误?

Locale::getLanguage将返回3个字母的代码似乎是一个错误。Javadoc在其代码示例中使用了两个字母的代码。但不幸的是,Javadoc没有明确指定2个或3个字母。我建议您向OpenJDK项目提交一个请求,以澄清此Java代码。

解决方法

作为一种解决办法,您或许可以调用Locale.getISOLanguages来获取所有已知语言的两个字母代码的数组。然后把那些循环起来。对于每个对象,使用在Javadoc中看到的代码,传递两个字母的代码来限制Locale对象进行比较:

if (locale.getLanguage().equals(new Locale("he").getLanguage()))

从此版本中,您可以在区域设置和两个字母的代码之间使用您自己的Map

示例类

这是我第一次尝试这样的变通地图。

在构造函数中,我们获得所有已知区域设置和所有已知2字母ISO 639-1语言代码的列表。

接下来,我们执行嵌套循环。对于每个地区,我们循环所有两个字母的语言代码,直到找到匹配项。注意,我们做的是而不是进行字符串匹配。Javadoc警告我们ISO 639标准不是稳定的;代码正在更改。报价:

注意:ISO 639不是一个稳定的标准-某些语言的代码已更改。Locale的构造函数可以识别代码已更改的语言的新代码和旧代码,但此函数始终返回旧代码。如果要检查代码已更改的特定语言,请不要执行以下操作

if (locale.getLanguage().equals("he")) // BAD!

相反,请执行

if (locale.getLanguage().equals(new Locale("he").getLanguage())) // GOOD.

因此,我们的内部循环查看每个已知的两个字母的语言代码,并获取该语言的Locale对象。然后,if语句比较getLanguage的输出(A)外部循环的Locale和(B)内部循环生成的仅语言的Locale(由两个字母的代码生成)。在您情况下,您声称某个设备正在为我们对getLanguage的调用输出3个字母的代码值。但无论是2个字母还是3个字母,都无关紧要。我们只是在寻找匹配项。

实例化后,我们可以通过调用lookupTwoLetterLanguageCode方法向LocaleLookup实例请求匹配特定Locale的两个字母的代码。

LocaleLookup localeLookup = new LocaleLookup();
Locale locale = Locale.CANADA_FRENCH;
String code = localeLookup.lookupTwoLetterLanguageCode( locale );

System.out.println( "Locale: " + locale.toString() + " " + locale.getDisplayName( Locale.getDefault() ) + " | ISO 639-1 code: " + code );

区域设置:FR_CA法语(加拿大)|ISO 639-1代码:FR

我只是在猜测这一切。我没有仔细考虑过,也没有测试过任何这一点。所以买家-当心,这个解决方案值你花的每一分钱。祝你好运。

这是整个类,其中public static void main用作演示。

package work.basil.example;

import java.util.*;

public class LocaleLookup
{
    private Map < Locale, String > mapLocaleToTwoLetterLangCode;

    public LocaleLookup ( )
    {
        this.mapLocaleToTwoLetterLangCode = new HashMap <>( Locale.getAvailableLocales().length );
        this.makeMaps();
        System.out.println( "mapLocaleToTwoLetterLangCode = " + mapLocaleToTwoLetterLangCode );
    }

    private void makeMaps ( )
    {
        // Get all locales.
        Set < Locale > locales = Set.of( Locale.getAvailableLocales() );


        // Get all languages, per 2-letter code.
        Set < String > twoLetterLanguageCodes = Set.of( Locale.getISOLanguages() ); // Returns: An array of ISO 639 two-letter language codes.

        for ( Locale locale : locales )
        {
            for ( String twoLetterLanguageCode : twoLetterLanguageCodes )
            {
                if ( locale.getLanguage().equals( new Locale( twoLetterLanguageCode ).getLanguage() ) )
                {
                    this.mapLocaleToTwoLetterLangCode.put( locale , twoLetterLanguageCode );
                    break;
                }
            }
        }
//        System.out.println( "locales = " + locales );
//        System.out.println( "twoLetterLanguageCodes = " + twoLetterLanguageCodes );
    }

    public String lookupTwoLetterLanguageCode ( final Locale locale )
    {
        String code = this.mapLocaleToTwoLetterLangCode.get( locale );
        Objects.requireNonNull( code );
        return code;
    }


    public static void main ( String[] args )
    {
        LocaleLookup localeLookup = new LocaleLookup();
        Locale locale = Locale.CANADA_FRENCH;
        String code = localeLookup.lookupTwoLetterLanguageCode( locale );

        System.out.println( "Locale: " + locale.toString() + " " + locale.getDisplayName( Locale.getDefault() ) + " | ISO 639-1 code: " + code );
    }
}

这是我在Java 15预发布版本中生成的映射。注意可能是不正确的,因为我在预发布版本中看到了一些关于区域设置的错误。

这篇关于将语言代码三个字符(ISO 639-2)转换为两个字符代码(ISO 639-1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1158

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1059

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this-&gt;id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:798

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this-&gt;id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:884

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:925

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:870

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:854

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:825

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1688

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1294