当前位置: 首页 > news >正文

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

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,我们要截取出dddds0 = 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,我们要截取出dddds0 = 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 思否

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 对称加密和非对称加密解析
  • 关于力扣150题目——逆波兰表达式求值Java实现的三种解法
  • 如何写好品牌宣传稿提升品牌曝光?看这篇文章就够了
  • Java虚拟机(JVM):深入理解与性能调优
  • 如何在应用运行时定期监控内存使用情况
  • “LNMP环境搭建实战指南:从零开始配置CentOS 7下的Nginx、MySQL与PHP“
  • C# —— Directory类
  • Java 中的异常处理机制是如何工作的?请解释 try-catch-finally 的基本用法?
  • 如何远程访问运行电脑上运行的程序?
  • 【知网CNKI-注册安全分析报告】
  • C++:filter2D函数简要概述
  • 手撸俄罗斯方块(一)——简单介绍
  • 解决Invalid or unsupported by client SCRAM mechanisms(dbeaver)
  • Golang 基于 archive/zip 包实现文件
  • ontape备份异机还原的样例
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 分享的文章《人生如棋》
  • [译]CSS 居中(Center)方法大合集
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 5、React组件事件详解
  • flutter的key在widget list的作用以及必要性
  • Git学习与使用心得(1)—— 初始化
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript设计模式与开发实践系列之策略模式
  • jQuery(一)
  • js数组之filter
  • mysql innodb 索引使用指南
  • Rancher-k8s加速安装文档
  • storm drpc实例
  • Vue小说阅读器(仿追书神器)
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 面试总结JavaScript篇
  • 巧用 TypeScript (一)
  • 使用putty远程连接linux
  • 项目实战-Api的解决方案
  • 一份游戏开发学习路线
  • 阿里云ACE认证之理解CDN技术
  • ​flutter 代码混淆
  • #、%和$符号在OGNL表达式中经常出现
  • (3) cmake编译多个cpp文件
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (k8s)Kubernetes本地存储接入
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (SpringBoot)第七章:SpringBoot日志文件
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (十) 初识 Docker file
  • (四)图像的%2线性拉伸
  • (一)u-boot-nand.bin的下载
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)