"İ".toLowerCase() != "i"

19

在土耳其语中,有一个字母İ,是小写字母i的大写形式。但当我将它转换为小写字母时,结果很奇怪。例如:

var string_tr = "İ".toLowerCase();
var string_en = "i";

console.log( string_tr == string_en );  // false
console.log( string_tr.split("") );     // ["i", "̇"]
console.log( string_tr.charCodeAt(1) ); // 775
console.log( string_en.charCodeAt(0) ); // 105

"İ".toLowerCase()返回了一个额外的字符,如果我没记错的话,它是COMBINING DOT ABOVE (U+0307)

我该如何去除这个字符?

我可以直接过滤字符串:

var string_tr = "İ".toLowerCase();

string_tr = string_tr.split("").filter(function (item) {
    if (item.charCodeAt(0) != 775) {
        return true;
    }
}).join("");

console.log(string_tr.split(""));

但是我是否正确处理了这个问题呢?有没有更好的方法?此外,为什么会出现这个额外的字符?

存在一些不一致性。例如,在土耳其语中,有一个小写形式的 Iı。为什么以下比较返回 true 呢?

console.log( "ı".toUpperCase() == "i".toUpperCase() ) // true

console.log( "İ".toLowerCase() == "i" ) // false

返回 false?


9
你尝试过使用 String.toLocaleLowerCase() 吗?https://dev59.com/lHI-5IYBdhLWcg3wcn7m - Tobias Timm
3
您可以在这里阅读更多相关信息:https://msdn.microsoft.com/zh-cn/library/ms973919.aspx#stringsinnet20_topic5 - JOSEFtw
1
@akinuri,因为ı(U+0131)i(U+0069)的映射是相同的:I(U+0049) - MinusFour
@MinusFour 嗯,他们不能把 İ 映射到 i 而不是 i + COMBINING DOT ABOVE 吗?目前的映射似乎有点荒谬。 - akinuri
1
@akinuri,这会破坏依赖于该行为的人的一些代码。说实话,这并不荒谬... 无论何时,这就是Unicode为土耳其语添加特殊情况的原因。这就是为什么您需要使用.toLocaleLowerCase - MinusFour
显示剩余2条评论
2个回答

33
你需要进行土耳其语特定的大小写转换,可以使用 String#toLocaleLowerCase 方法:

let s = "İ";

console.log(s.toLowerCase().length);
console.log(s.toLocaleLowerCase('tr-TR').length);


1
这仅在我了解字符串的语言环境的情况下才有用,是吗?例如,用户在表格中输入字符串,但我无法知道字符串的语言环境。那么我该怎么办?还是为了安全起见使用 .toLocaleLowerCase('tr-TR')?在这种情况下,每个字符串都使用 .toLocaleLowerCase('tr-TR') 是安全的吗? - akinuri
9
不,这并不安全(尝试将“I”转换为小写)。通常情况下,您需要知道字符串的本地设置才能正确地进行转换。对于特定情况,可能会有解决方法 - 您将字符串转换为小写的原因是什么? - Ry-
6
由于没有通用的大小写映射方法,因此您必须知道具体是哪种语言。同样的情况也出现在排序中,因为相同的字符串在不同语言中排序可能不同。这篇文章链接提供了更多相关信息:https://blogs.msdn.microsoft.com/oldnewthing/20030905-00/?p=42643 和 https://learn.microsoft.com/en-us/globalization/locale/sorting-and-string-comparison 以及 http://www.unicode.org/reports/tr10/#Introduction。 - phuclv
2
@akinuri:艺术家的名字?你需要将它们转换为小写字母,还是不区分大小写的比较就足够了?但是,语言确实是一个极其棘手的问题之一。 - Ry-
2
@Ryan 不区分大小写的比较也需要指定语言环境吗? - Barmar
显示剩余9条评论

0

对于土耳其语和其他带有点和无点i版本的字母表,例如阿塞拜疆语、哈萨克语、鞑靼语和克里米亚鞑靼语,您可以使用LocalLowerCase或LocalUpperCase。

var string_tr = "İ".toLocalLowerCase();
var string_en = "i";

console.log( string_tr == string_en );  // false
console.log( string_tr.split("") );     // ["i", "̇"]
console.log( string_tr.charCodeAt(1) ); // 775
console.log( string_en.charCodeAt(0) ); // 105


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接