0 &#xff0c 、&#11111……是什么鬼?

最近,要将一些网页内容复制到<textarea>文本框中作进一步处理,发现有些网页内容中包含&#xff0c或&#11111;之类的标记,会被原样复制到<textarea>文本框中。
如果将这些网页内容直接使用document.write()输出,那么&#xff0c之类的标记会自动显示为对应的字符。
这是怎么回事呢?

1  Numeric Character Reference(NCR)简介

在网上查了一下,&#xff0c或&#11111;之类的是一种叫做 Numeric Character Reference(NCR)的标记结构。

1.1  Wikipedia(维基百科)上的解释
 Wikipedia(维基百科)上的解释是:

A numeric character reference (NCR) is a common markup construct used in SGML and other SGML-based markup languages such as HTML and XML. It consists of a short sequence of characters that, in turn, represent a single character from the Universal Character Set (UCS) of Unicode. NCRs are typically used in order to represent characters that are not directly encodable in a particular document. When the document is interpreted by a markup-aware reader, each NCR is treated as if it were the character it represents.

bing的翻译如下:

数字字符引用 (NCR) 是 SGML 和其他基于 SGML 的标记语言(如 HTML 和 XML)中使用的常见标记结构。它由一小段字符组成,这些字符又表示 Unicode 通用字符集 (UCS) 中的单个字符。NCR 通常用于表示在特定文档中无法直接编码的字符。当文档由标记感知阅读器解释时,每个 NCR 都被视为它所代表的字符。

1.2 NCR标记的结构

NCR标记由三个部分组成:

1

2

3

&#

字符的Unicode编码值(可以是10或16进制)

;

NCR标记以&#开头, 后面跟着字符的Unicode编码值,最后以一个半角分号结束。 

其中字符的Unicode编码值可以使用10进制或16进制,其中16进制值以要x开头。如:

字符

NCR(10进制)

NCR(16进制)


&#31243;

&#x7a0b;


&#5e8f;

&#24207;


&#21592;

&#x5458;

 2 JavaScript编程进行NCR转换

2.1 常规思路

1.定义一个数组保存NCR第1部分的字符串:var aNCR = ['&#x','&#']; 

2.使用String对象的.indexOf()方法搜索aNCR中的数组元素

3.搜索到aNCR中的数组元素,使用String对象的fromCharCode()方法获取对应的字符

4.继续2,直到不再发现NCR中的数组元素

程序流程图如下:

用JavaScript将 NCR(Numeric Character Reference)标记转换为对应字符的方法_NCR

2.2 编写函数tranNCR()

//功能:将字符串中的所有NCR转换为对应字符
//输入:s=字符串
//输出:转换后的字符串
//日志:20240710创建
function tranNCR(s)
{
	var aNCR = ['&#x','&#'];
	var s0 = s;
	var i, j ,k;
	for (k = 0 ; k < aNCR.length; k++)
	{
		i = s0.indexOf(aNCR[k]);

		while (-1 != i)
		{
			j = s0.substring(0).indexOf(';');
			if (-1 == j)	 //未发现结束符‘;’
			{
				return s0;
			}

			//document.write('<p>',s0.substring(i+aNCR[k].length-1, j))

			// 对于16进制的#&xhhhh;,我们要截取出xhhhh,并在前面加上'0‘;
            // 对于10进制的#&dddd,我们要截取出dddd
			s0 = s0.substring(0,i) + String.fromCharCode(k==0 ? ('0'+ s0.substring(i+aNCR[k].length-1, j)) : s0.substring(i+aNCR[k].length, j))  + s0.substring(j+1);

			i = s0.indexOf(aNCR[k]);
		} // while(i)
	} // for(k)
	return s0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

 2.3 演示代码

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="PurpleEndurer">
	<title>将字符串中的所有NCR转换为对应字符</title>
</head>
<body>
	<p>转换后的结果:</p>
	<textarea id="taTarget" cols="80" rows="15"></textarea>

<script>
//功能:将字符串中的所有NCR转换为对应字符
//输入:s=字符串
//输出:转换后的字符串
//日志:20240710创建
function tranNCR(s)
{
	var aNCR = ['&#x','&#'];
	var s0 = s;
	var i, j ,k;
	for (k = 0 ; k < aNCR.length; k++)
	{
		i = s0.indexOf(aNCR[k]);

		while (-1 != i)
		{
			j = s0.substring(0).indexOf(';');
			if (-1 == j)	 //未发现结束符‘;’
			{
				return s0;
			}

			//document.write('<p>', s0.substring(i+aNCR[k].length-1, j))

			// 对于16进制的#&xhhhh;,我们要截取出xhhhh,并在前面加上'0‘
			// 对于10进制的#&dddd,我们要截取出dddd
			s0 = s0.substring(0,i) + String.fromCharCode(k==0 ? ('0'+ s0.substring(i+aNCR[k].length-1, j)) : s0.substring(i+aNCR[k].length, j))  + s0.substring(j+1);

			i = s0.indexOf(aNCR[k]);
		} // while(i)
	} // for(k)
	return s0;
}

s = '我们是程 序 员~~'; 

var taTarget = document.getElementById("taTarget");
taTarget.value = tranNCR(s);
document.write('<p>正确结果:',s);
</script>

</body>
</html>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.

程序运行结果如下: 

 

用JavaScript将 NCR(Numeric Character Reference)标记转换为对应字符的方法_ecmascript_02

2.4 用正则表达式实现

 对于熟悉正则表述式的高手来说,用正则表达式实现可以代码更简捷。

在网上搜索到了网友Joebon用正则表达式来实现转换的演示代码(见参考2):

var regex_num_set = /&#(\d+);/g;
var str = "Here is some text: 每日一色|蓝白~"

str = str.replace(regex_num_set, function(_, $1) {
  return String.fromCharCode($1);
});

document.write('<pre>'+JSON.stringify(str,0,3));
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

代码运行结果:

用JavaScript将 NCR(Numeric Character Reference)标记转换为对应字符的方法_开发语言_03

其思路是用String.prototype.replace() 和方法 将字符串中的 NCR 字符逐个获取到 ""和";"间的 Unicode 字符编码值, 然后利用 String.fromCharCode() 方法, 将 Unicode 编码转为对应的字符。

3 参考资料

1.  Numeric character reference - Wikipedia, the free encyclopedia (zubiaga.org)

2.javascript - 将 NCR(Numeric Character Reference) 字符转换为真实字符的方法 - Joebon的前端世界