拜托,拜托,永远不要盲目地删除文本块,尤其是不仅仅是因为你看不到或理解它们;它会破坏信息。有人把它们放在那里是有原因的;包含表情符号的推文通常没有表情符号就没有任何意义。
就其价值而言,您所看到的并不是真正的“二进制”;它很可能是一个小方块,Unicode 代码点以十六进制拼写。对于?,那是 U+1F49C,所以你可能会看到 0 1 F 4 9 C。当您安装的字体都没有字形时,这就是 Unicode 字符的呈现方式。
要真正看到字符,您有多种选择。
- 从here 获取 Symbola,并安装它。现在你可以看到表情符号了。但没有其他人可以。
-
获取 Symbola,并使用 @font-face 块将其添加到您的网站,如下所示:
@font-face {
font-family: Symbola;
src: url('Symbola.ttf') format('truetype');
unicode-range: U+1F???;
}
然后使用font-family: Symbola, "your preferred font", sans-serif; 设置页面的字体。
这样做的缺点是,据我了解,CSS 的 font-family 选择了第一个存在的字体,并且 没有 指定 Unicode 后备。因此,在不支持 unicode-range (Firefox) 的浏览器中,这会将您的整个页面呈现在不是特别漂亮的 Symbola 中。
您可以通过查找所有表情符号并将它们包装在 <span class="emoji"> 中来解决这个问题,然后仅将 Symbola 用于 .emoji 元素。
找到所有表情符号并将它们替换为<img> 标签,就像 Twitter 一样。 Twitter 的图片都位于包含代码点的 URL,例如https://abs.twimg.com/emoji/v1/72x72/1f43e.png,所以重用它们就很容易了。 (实际上,Twitter API 不会为您执行此操作,我有点惊讶。)
如果您想查找并替换所有表情符号,您可能只想查找所有星界字符——即那些不在现代人类语言所在的基本多语言位面的字符。这些都是代码点为 U+10000 及以上的字符。
在 JavaScript 中,字符串并不是真正的字符串。它们是 16 位数字的数组。 16 位是四个十六进制数字,因此具有五个十六进制数字的 Unicode 代码点不适合单个 16 位数字。相反,JavaScript 使用可怕的 UTF-16 编码对它们进行编码,该编码使用两个 16 位数字:一个在 0xD800 到 0xDBFF 范围内,一个在 0xDC00 到 0xDFFF 范围内。两个数字一起称为“代理对”。这些数字都不会是真正的 Unicode 代码点;为这种编码保留了整个块。
要查找所有星光层字符,您实际上是要查找所有代理对:
/[\uD800-\uDBFF][\uDC00-\uDFFF]/
因此,Twitter 的图片替换实现可能如下所示:
var text = "hey babe ? how you doin";
// Split on surrogate pairs, and preserve the surrogates; this will give
// you an array that alternates between BMP text and a single surrogate
// pair: [text, emoji, text, emoji, text...]
var chunks = text.split(/([\uD800-\uDBFF][\uDC00-\uDFFF])/);
// A DocumentFragment is a DOM tree that can be manipulated freely without
// causing a reflow, so it's more performant for heavy tree-building and a
// good habit to get into
var frag = document.createDocumentFragment();
for (var i = 0, l = chunks.length; i < l; i++) {
if (i % 2 == 0) {
// Even-numbered chunks are plain text
frag.appendChild(document.createTextNode(chunks[i]));
}
else {
// Odd-numbered chunks are surrogate pairs
// We have TWO characters, but we want one codepoint; this is how
// you decode UTF-16 :(
var pair = chunks[i];
var codepoint = (
0x10000
| ((pair.charCodeAt(0) - 0xD800) << 10)
| (pair.charCodeAt(1) - 0xDC00)
);
var hex = codepoint.toString(16); // now it's in hex
var img = document.createElement('img');
img.src = "https://abs.twimg.com/emoji/v1/72x72/" + hex + ".png";
// Twitter uses pretty big images and just scales them down
// clientside; you could change these to whatever you want, or add
// a class here and use CSS to set the width/height to 1em to
// match the current font size
img.height = 16;
img.width = 16;
frag.appendChild(img);
}
}
// Now just stick it into the page somewhere
var el = document.createElement('p');
el.appendChild(frag);
document.body.appendChild(el);
这将根据选项 3 创建一个 <img>,但您也可以轻松添加一个 <span class="emoji"> 并使用选项 2。或者做任何其他您想做的事情,例如将表情符号替换为 Unicode 名称。 (Twitter 在每张图片上都有 Unicode 名称 title,但这里没有这样做,因为它需要包含一个巨大的列表,将代码点映射到名称☺)