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

news2024/9/24 5:33:19

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标记由三个部分组成:

123
&#字符的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中的数组元素

程序流程图如下:

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;
}

 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 = '我们是&#x7a0b; &#x5e8f; &#x5458;~~'; 

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

</body>
</html>

程序运行结果如下: 

 

2.4 用正则表达式实现

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

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

var regex_num_set = /&#(\d+);/g;
var str = "Here is some text: &#27599;&#26085;&#19968;&#33394;|&#34013;&#30333;~"

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

document.write('<pre>'+JSON.stringify(str,0,3));

代码运行结果:

其思路是用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的前端世界 - SegmentFault 思否

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1915311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI Agent 的发展现状、行业结构与趋势分析

Agent 来自一种哲学概念&#xff0c;是个很古老的哲学术语&#xff0c;从哲学意义上讲&#xff0c;“代理”的概念涉及实体的自主性&#xff0c;具有行使意志、做出选择和采取行动的能力&#xff0c;而不是被动地对外部刺激做出反应。后来人们将这一概念引入计算机科学领域&…

285个地级市-胡焕庸线数据

全国285个地级市-胡焕庸线数据.zip资源-CSDN文库 胡焕庸线&#xff1a;中国人口与生态的分界线 胡焕庸线&#xff0c;一条在中国地理学界具有划时代意义的分界线&#xff0c;由著名地理学家胡焕庸于1935年提出。这条线从黑龙江省的瑷珲&#xff08;现黑河市&#xff09;延伸至…

又上热搜!曝iPhone 16将支持40W快充

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 7月9日晚&#xff0c;微博话题“iPhone16系列或将支持40W快充”上了热搜榜&#xff0c;这已经是iPhone 16系列第N次上热搜了。 据爆料&#xff0c;iPhone 16系列充电功率将提升至40W&#xff0c;并且…

Deepspeed : AttributeError: ‘DummyOptim‘ object has no attribute ‘step‘

题意&#xff1a;尝试在一个名为 DummyOptim 的对象上调用 .step() 方法&#xff0c;但是这个对象并没有定义这个方法 问题背景&#xff1a; I want to use deepspeed for training LLMs along with Huggingface Trainer. But when I use deepspeed along with trainer I get …

书生大模型实战营(暑假场)-入门岛-第二关

目录 关卡任务 任务一 任务二 总结 关卡任务 任务一&#xff1a; 请实现一个wordcount函数&#xff0c;统计英文字符串中每个单词出现的次数。返回一个字典&#xff0c;key为单词&#xff0c;value为对应单词出现的次数。 这个算是比较简单的了&#xff0c;代码如下所示 …

C基础day8

一、思维导图 二、课后习题 #include<myhead.h> #define Max_Stu 100 //函数声明 //学生信息录入函数 void Enter_stu(int *Num_Stu,char Stu_name[][50],int Stu_score[]); //查看学生信息 void Print_stu(int Num_Stu,char Stu_name[][50],int Stu_score[]); //求出成绩…

Rust vs Go: 特点与应用场景分析

目录 介绍Rust的特点Go的特点Rust的应用场景Go的应用场景总结 介绍 Rust和Go&#xff08;Golang&#xff09;是现代编程语言中两个非常流行的选择。凭借各自的独特优势和广泛的应用场景&#xff0c;吸引了大量开发者的关注。本文将详细介绍Rust和Go的特点&#xff0c;并探讨它…

OpenCV 寻找棋盘格角点及绘制

目录 一、概念 二、代码 2.1实现步骤 2.2完整代码 三、实现效果 一、概念 寻找棋盘格角点&#xff08;Checkerboard Corners&#xff09;是计算机视觉中相机标定&#xff08;Camera Calibration&#xff09;过程的重要步骤。 OpenCV 提供了函数 cv2.findChessboardCorners…

C++ 宏和内联、范围for、nullptr

C 宏函数和内联函数、范围for、nullptr 宏函数和内联函数 ​ 函数重载中提到过&#xff0c;一个程序编译需要经过四个阶段&#xff0c;第一个阶段预处理中有一个操作是宏替换。由于是替换&#xff0c;所以宏不建立栈帧&#xff0c;且没有数据类型的限制&#xff0c;能够提高我…

ESP-12F 异常烧录一例

自己打了一块esp8266 &#xff0c;esp 12f的模组&#xff0c;品牌是B&T ,某公司的子品牌吧。 玩单片机这么久&#xff0c;终于玩到了自己打nodemcu这种版了。 遇到一些问题汇总如下供参考&#xff1a; 1&#xff0c;模组IO2自带了led,后来只能拆了我画的线路&#xff0c;…

Canvas:实现在线画板操作

想象一下&#xff0c;用几行代码就能创造出如此逼真的图像和动画&#xff0c;仿佛将艺术与科技完美融合&#xff0c;前端开发的Canvas技术正是这个数字化时代中最具魔力的一环&#xff0c;它不仅仅是网页的一部分&#xff0c;更是一个无限创意的画布&#xff0c;一个让你的想象…

前后端如何实现非对称加解密-使用RSA为例讲解!

写在最前面&#xff0c;RSA是一种非对称加密算法&#xff0c;使用不同的公钥和私钥进行加密和解密。 下面是使用RSA进行加密和解密的代码示例&#xff1a; 前端&#xff1a;使用CryptoJS进行RSA加密 在前端JavaScript中&#xff0c;使用jsencrypt库来进行RSA加密&#xff1a…

04OLED简介和调试方法

OLED简介和调试方法 调试方式串口调试显示屏调试其他调试方法总结&#xff1a; OLED简介硬件电路OLED驱动函数 keil调试模式进入方法keil调试界面窗口简单功能说明更加强大的功能 调试方式 电脑想看什么变量可以直接打印到屏幕&#xff0c;但是单片机很多时候由于成本和电路结构…

充电桩运营平台的技术方案 53页

充电桩运营平台的技术方案 53页&#xff0c;全套解决方案 内容太多&#xff0c;复制图片丢失&#xff0c;需要完整的私信我。

图片kb太大了怎么改小?修改图片kb的方法介绍

图片kb太大了怎么改小&#xff1f;将图片的文件大小&#xff08;以KB为单位&#xff09;缩小可以带来多种优点&#xff0c;但也有一些缺点需要注意。缩小图片文件大小可以显著减少它在硬盘或其他存储设备上占用的空间&#xff0c;使你能够存储更多的图片和其他文件。而且&#…

Postman使用教程【项目实战】

目录 引言软件下载及安装项目开发流程1. 创建项目2. 创建集合(理解为&#xff1a;功能模块)3. 设置环境变量&#xff0c;4. 创建请求5. 测试脚本6. 响应分析7. 共享与协作 结语 引言 Postman 是一款功能强大的 API 开发工具&#xff0c;它可以帮助开发者测试、开发和调试 API。…

制造业中SCADA与MES系统承担着怎样的重任?

SCADA&#xff08;Supervisory Control and Data Acquisition&#xff09;是一种广泛应用于工业控制系统中的监控和数据采集系统。它主要用于监控和控制工业过程中的设备和活动&#xff0c;并收集相关数据以供分析和优化。SCADA系统由人机界面&#xff08;HMI&#xff09;、数据…

提醒我每天打卡的“目标打卡提醒软件”

在繁忙的生活中&#xff0c;我们总有许多需要每日坚持的习惯&#xff0c;无论是为了健康而设定的减肥计划&#xff0c;还是为了工作而必须的每日上班打卡&#xff0c;亦或是为了自我提升而规定的每日学习任务。这些日常打卡活动&#xff0c;虽然重要&#xff0c;但在忙碌和疲惫…

罗马仕和西圣充电宝好用吗?西圣、倍思充电宝实测大PK!

随着智能设备在日常生活中的普及&#xff0c;充电宝成为了人们出行必备的数码配件。市场上充电宝品牌琳琅满目&#xff0c;其中罗马仕、西圣和倍思是较为知名的品牌。它们各自有着什么样的特点和优势呢&#xff1f;为了帮助大家更好地选择适合自己的充电宝&#xff0c;我们特意…

“我没钱”最好别用“I have no money“,老外很少这样说!成人学英语到柯桥泓畅学校

说到没钱都有话说&#xff0c;那我们怎么用英语表达&#xff1f;是不是直接说I have no money&#xff0c;老外表示很少这样说&#xff0c;那下面一起来拓展下&#xff1a; 老外如何地道表达“我没钱”&#xff1f; 当我们想表达“我没钱”时&#xff0c;很多人的第一反应就是…