根据用户区域设置过滤字符串列表 [英] Filtering a list of strings based on user locale

查看:76
本文介绍了根据用户区域设置过滤字符串列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用AngularJS 1.6处理JavaScript项目时,我有一个我想要过滤的字符串列表。例如,假设我的列表包含árbolcigüeña nido tubo

When working on a JavaScript project with AngularJS 1.6, I have a list of strings which I'd like to filter. For instance, assume my list contains árbol, cigüeña, nido and tubo.

当用西班牙语过滤字符串时,如果我过滤了u,我会期望出现cigüeña tubo ,这将是西班牙人最自然的结果。然而,德语并非如此 - 你和ü是不同的字母,因此德国人不希望在名单上看到cigüeña。所以我正在寻找一种方法让我的列表过滤知道用户的语言环境。

When filtering strings in Spanish, if I filtered for "u", I'd expect both cigüeña and tubo to appear, which would be the most natural result for a Spaniard. However, this is not the case in German - u and ü are different letters and thus a German will not want to see cigüeña on the list. So I am looking for a way to make my list filtering aware of the user's locale.

我碰巧有一个包含许多变音符号的对象,这样:

I happen to have an object containing lots of diacritics, such that:

diacritics["á"] = "a";
diacritics["ü"] = "u";
// and so on...

这就是我的过滤代码:

This is what my filtering code looks like:

function matches(word, search) {
    var cleanWord = removeDiacritics(word.toLowerCase());
    var cleanSearch = removeDiacritics(search.toLowerCase());
    return cleanWord.indexOf(cleanSearch) > -1;
}

function removeDiacritics(word) {
    function match(a) {
        return diacritics[a] || a;
    }
    return text.replace(/[^\u0000-\u007E]/g, match);
}

上面的代码只删除了所有变音符号,所以我想让它知道用户的语言环境。因此,我将match()函数更改为:

The above code just removes all diacritics, so I thought to make it aware of the user's locale. Thus, I changed the match() function to this:

function match(a) {
    if (diacritics[a] && a.localeCompare(diacritics[a] === 0) {
        return diacritics[a];
    }
    return a;
}

不幸的是,这不起作用。当比较u和ü时,localeCompare函数返回相同的值有德语和西班牙语的语言环境,所以这不是答案。我已经过了 localeCompare方法的参考并尝试了使用和灵敏度选项,但它们似乎没有多大帮助。

Unfortunately, this doesn't work. The localeCompare function returns the same values when comparing "u" and "ü" with the German and Spanish locales, so that was not the answer here. I've gone over the reference for the localeCompare method and tried the usage and sensitivity options, but they don't seem to help much here.

我怎么能调整我的代码才能正常工作?是否有任何库可以为我正确处理?

How could I tweak my code for this to work? Is there any library which can handle this properly for me?

推荐答案

我通过 navigator <直接从浏览器获取用户的语言环境/ code>( src ),一个对象代表用户代理:

I'd go about getting the user's locale directly from the browser via navigator (src), an object representing the user agent:

var language = navigator.language;

这将分配语言的区域代码用户的浏览器,在我的情况下 en-US 。我发现此网站有助于查找区域代码以测试其他区域世界。

This will assign language the locale code of the user's browser, in my case en-US. I found this site helpful for finding locale code's to test other regions of the world.

我的 strFromLocale 功能与您的 removeDiacritics function:

My strFromLocale function is comparable to your removeDiacritics function:

function strFromLocale(str) {
    function match(letter) {
        function letterMatch(letter, normalizedLetter) {
            var location = new Intl.Collator(language, {usage: 'search', sensitivity: 'base' }).compare(letter, normalizedLetter);
            return (location == 0)
        }
        normalizedLetter = letter.normalize('NFD').replace(/[\u0300-\u036f]/gi, "")
        if ( letterMatch(letter, normalizedLetter) ) {
            return normalizedLetter;
        } else {
            return letter;
        }
    }
    return str.replace(/[^\u0000-\u007E]/g, match);
}

注意 Intl.Collat​​or src )。该行将变音符号与变音符号的标准化字母进行比较,并检查给定语言的字母表中的位置差异。因此:

Note the line with Intl.Collator (src). This line compares the diacritic with the normalized letter of the diacritic and checks the given language's alphabet for positional differences. Therefore:

/* English */
new Intl.Collator('en-US', {usage: 'search', sensitivity: 'base' }).compare('u', 'ü');
>>> 0

/* Swedish */
new Intl.Collator('sv', {usage: 'search', sensitivity: 'base' }).compare('u', 'ü');
>>> -1

/* German */
new Intl.Collator('de', {usage: 'search', sensitivity: 'base' }).compare('u', 'ü');
>>> -1

正如您在 letterMatch function,当且仅当 Intl.Collat​​or 的结果为 0 时才返回true,表示没有该语言字母表中字母的位置差异意味着可以安全地替换。

As you can see in the letterMatch function, it returns true if and only if the result of Intl.Collator is 0, indicating that there are no positional differences of the letter within the alphabet of that language meaning it is safe to replace.

有了这个,这里有一些 strFromLocale的测试 function:

With that, here are some tests of the strFromLocale function:

var language = navigator.language; // en-US
strFromLocale("cigüeña");
>>> ciguena

var language = 'sv' // Swedish
strFromLocale("cigüeña");
>>> cigüena

var language = 'de' // German
strFromLocale("cigüeña");
>>> cigüena

var language = 'es-mx' // Spanish - Mexico
strFromLocale("cigüeña");
>>> cigueña

这篇关于根据用户区域设置过滤字符串列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆