如何使用 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 但它与其他字符冲突:(