如何使用 Javascript 比较 "M" 和“M”(UTF 格式)?
How can I compare "M" and "M" (in UTF) using Javascript?
我有一种情况,如果网格包含某个子字符串,我就必须搜索它。我有一个搜索栏,用户可以在其中键入字符串。问题是网格包含日语文本和 Unicode 字符的混合,
例如:MAGシンチ注〓333MB1。
如何比较我从键盘输入的字母 'M' 和上例中的字母“M”的内容相等性?我正在尝试使用纯 Javascript 而不是 Jquery 或其他库来执行此操作。我必须在 Internet Explorer 中执行此操作。
谢谢,
正如@Rhymoid 对这个问题的深刻评论中提到的,现代 JavaScript (ES2015) 包括对 Unicode 的 规范化 的支持。一种规范化模式是将 "compatible" 字母形式从较高代码页映射到它们在较低代码页中的最基本代表(总而言之,它有点复杂)。 .normalize("NFKD")
方法会将 "M" 从日文代码页映射到对应的拉丁文代码页。于是
"MAGシンチ注 333MBq".normalize("NFKD")
会给
"MAGシンチ注 333MBq"
截至 2016 年底,IE 不支持 .normalize()
。
在较低级别,ES2015 也有 .codePointAt()
(在另一个好的答案中提到),它类似于下面描述的旧 .charCodeAt()
,但它也理解 UTF-16 对。但是,.codePointAt()
(同样是在 2016 年底)不受 Safari 支持。
以下是旧版浏览器的原始答案
您可以使用.charCodeAt()
方法检查字符串中的UTF-16字符编码。
"M".charCodeAt(0)
是77,而
"M".charCodeAt(0)
是65325。
对于某些 Unicode 字符,UTF-16 表示涉及 JavaScript 字符串中两个单独的字符位置,因此这种方法很复杂。该语言不提供处理该问题的本机支持,因此您必须自己做。 55926 和 57343(D800 和 DFFF 十六进制)之间的字符代码指示双字符对的开始。 The UTF-16 Wikipedia page has more information,还有其他各种来源。
我假设您可以通过其他方式阅读 DOM 来访问这些字符串。
如果是这样,codePointAt 将成为你的朋友。
console.log("Test of values");
console.log("M".codePointAt(0));
console.log("M".codePointAt(0));
console.log("Determining end of string");
console.log("M".codePointAt(10));
var str = "MAGシンチ注 333MBq .";
var idx = 0;
do {
point = str.codePointAt(idx);
idx++;
console.log(point);
} while(point !== undefined);
您可以尝试构建自己的字典并按如下方式比较函数:
var compareDB = {
'm' : ['M'],
'b' : ['B']
};
function doCompare(inputChar, searchText){
inputCharLower = inputChar.toLowerCase();
searchTextLower = searchText.toLowerCase();
if(searchTextLower.indexOf(inputChar) > -1)
return true;
if(compareDB[inputCharLower] !== undefined)
{
for(i=0; i<compareDB[inputCharLower].length; i++){
if(searchTextLower.indexOf(compareDB[inputCharLower][i].toLowerCase()) > -1)
return true;
}
}
return false;
}
console.log("searching with m");
console.log(doCompare('m', "searching text with M"));
console.log("searching with m");
console.log(doCompare('m', "searching text with B"));
console.log("searching with B");
console.log(doCompare('B', "searching text with B"));
构建字典应该适用于任何浏览器,在要转换的范围的开头找到字符代码,然后以您喜欢的方式移动字符,例如
function shift65248(str) {
var dict = {}, characters = [],
character, i;
for (i = 0; i < 10; ++i) { // 0 - 9
character = String.fromCharCode(65296 + i);
dict[character] = String.fromCharCode(48 + i);
characters.push(character);
}
for (i = 0; i < 26; ++i) { // A - Z
character = String.fromCharCode(65313 + i);
dict[character] = String.fromCharCode(65 + i);
characters.push(character);
}
for (i = 0; i < 26; ++i) { // a - z
character = String.fromCharCode(65313 + i);
dict[character] = String.fromCharCode(97 + i);
characters.push(character);
}
return str.replace(
new RegExp(characters.join('|'), 'g'),
function (m) {return dict[m];}
);
}
shift65248('MAGシンチ注 333MBq'); // "MAGシンチ注 333MBq"
我尝试将整个范围 65248..65375
移动到 0..127
但它与其他字符冲突:(
我有一种情况,如果网格包含某个子字符串,我就必须搜索它。我有一个搜索栏,用户可以在其中键入字符串。问题是网格包含日语文本和 Unicode 字符的混合, 例如:MAGシンチ注〓333MB1。
如何比较我从键盘输入的字母 'M' 和上例中的字母“M”的内容相等性?我正在尝试使用纯 Javascript 而不是 Jquery 或其他库来执行此操作。我必须在 Internet Explorer 中执行此操作。
谢谢,
正如@Rhymoid 对这个问题的深刻评论中提到的,现代 JavaScript (ES2015) 包括对 Unicode 的 规范化 的支持。一种规范化模式是将 "compatible" 字母形式从较高代码页映射到它们在较低代码页中的最基本代表(总而言之,它有点复杂)。 .normalize("NFKD")
方法会将 "M" 从日文代码页映射到对应的拉丁文代码页。于是
"MAGシンチ注 333MBq".normalize("NFKD")
会给
"MAGシンチ注 333MBq"
截至 2016 年底,IE 不支持 .normalize()
。
在较低级别,ES2015 也有 .codePointAt()
(在另一个好的答案中提到),它类似于下面描述的旧 .charCodeAt()
,但它也理解 UTF-16 对。但是,.codePointAt()
(同样是在 2016 年底)不受 Safari 支持。
以下是旧版浏览器的原始答案
您可以使用.charCodeAt()
方法检查字符串中的UTF-16字符编码。
"M".charCodeAt(0)
是77,而
"M".charCodeAt(0)
是65325。
对于某些 Unicode 字符,UTF-16 表示涉及 JavaScript 字符串中两个单独的字符位置,因此这种方法很复杂。该语言不提供处理该问题的本机支持,因此您必须自己做。 55926 和 57343(D800 和 DFFF 十六进制)之间的字符代码指示双字符对的开始。 The UTF-16 Wikipedia page has more information,还有其他各种来源。
我假设您可以通过其他方式阅读 DOM 来访问这些字符串。
如果是这样,codePointAt 将成为你的朋友。
console.log("Test of values");
console.log("M".codePointAt(0));
console.log("M".codePointAt(0));
console.log("Determining end of string");
console.log("M".codePointAt(10));
var str = "MAGシンチ注 333MBq .";
var idx = 0;
do {
point = str.codePointAt(idx);
idx++;
console.log(point);
} while(point !== undefined);
您可以尝试构建自己的字典并按如下方式比较函数:
var compareDB = {
'm' : ['M'],
'b' : ['B']
};
function doCompare(inputChar, searchText){
inputCharLower = inputChar.toLowerCase();
searchTextLower = searchText.toLowerCase();
if(searchTextLower.indexOf(inputChar) > -1)
return true;
if(compareDB[inputCharLower] !== undefined)
{
for(i=0; i<compareDB[inputCharLower].length; i++){
if(searchTextLower.indexOf(compareDB[inputCharLower][i].toLowerCase()) > -1)
return true;
}
}
return false;
}
console.log("searching with m");
console.log(doCompare('m', "searching text with M"));
console.log("searching with m");
console.log(doCompare('m', "searching text with B"));
console.log("searching with B");
console.log(doCompare('B', "searching text with B"));
构建字典应该适用于任何浏览器,在要转换的范围的开头找到字符代码,然后以您喜欢的方式移动字符,例如
function shift65248(str) {
var dict = {}, characters = [],
character, i;
for (i = 0; i < 10; ++i) { // 0 - 9
character = String.fromCharCode(65296 + i);
dict[character] = String.fromCharCode(48 + i);
characters.push(character);
}
for (i = 0; i < 26; ++i) { // A - Z
character = String.fromCharCode(65313 + i);
dict[character] = String.fromCharCode(65 + i);
characters.push(character);
}
for (i = 0; i < 26; ++i) { // a - z
character = String.fromCharCode(65313 + i);
dict[character] = String.fromCharCode(97 + i);
characters.push(character);
}
return str.replace(
new RegExp(characters.join('|'), 'g'),
function (m) {return dict[m];}
);
}
shift65248('MAGシンチ注 333MBq'); // "MAGシンチ注 333MBq"
我尝试将整个范围 65248..65375
移动到 0..127
但它与其他字符冲突:(