「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。
作者:Mintimate
Mintimate's Blog,只为与你分享
统计字数/字符
平时,在写一些报告时,需要统计字数;亦或者,我们在填写一些信息,有字数要求。这个时候,大部分人会打开Word,进行字数统计。这样效率过低,且无法模块化移植。(而且macOS启动Microsoft Word挺慢的😪……)
本次给大家介绍,如何使用JavaScrip前端统计输入内容所包含的字符和字数。稍微美化一下,放到服务器里,以后统计文字字数就不用等Word加载了🤔。
在线演示🖥
为了让大家更方便理解,什么是统计字数。我做了一个在线统计字数的网站。原理就是本篇文章:
实现逻辑🤖
首先,我们把段落才分成一个一个的字节,HTML
里我们打一个ID:content
,之后用JS用来获取用户输入的段落(标签我们使用textarea
标签):
// 获取段落内容
// jQuery
Words = $('#content').val();
// 原生JavaScript
Words = document.getElementById("content").value
当然,如果你使用Vue,那么可以这样:
<textarea
class="form-control"
@input="statisticAlpha"
placeholder="输入(或粘贴)统计字数的内容:"
rows="12"
v-model="inputContent"
autofocus>
</textarea>
也就是加上v-model
进行数据绑定。
对于拆分段落内容为字符,我们使用charAT
方法即可将字符串转为字符数组,配合循环遍历即可完成统计:
// 标点和中文
let sTotal = 0;
// 中文字判断
let iTotal = 0;
// 英文字母
let eTotal = 0;
// 数字判断
let inum = 0;
for (let i = 0; i < Words.length; i++) {
let c = Words.charAt(i);
if (c.match(***)) {
//判断后,实现的方法
}
}
最后的判断,也是个难题,如何判断?主要有两个要点:
- 正则表达式
- Unicode编码判断
判断规则⚖️
正则表达式
可以看到,我们前面逻辑判断语句:
let c = Words.charAt(i);
if (c.match(***)) {
//判断
}
其中的match
方法可能很多人平时没用,该方法是:可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
而正则表达式,是出自Unix,这注定正则表达式的泛用。使用正则表达式可以快速匹配目标内容。
举个例子,如果你要匹配一段字符串,是否包含字符abc,只需要用正则表达式:/[abc]/
即可。
Unicode编码
常用的编码,一般为UTF-8
、UTF-16
等。至于什么是编码,其实就是我们使用的文字对应一个机械代码:
# helloworld
\u0068\u0065\u006c\u006c\u006f\u0077\u006f\u0072\u006c\u0064
而Unicode上,不同国家的字集是分区块的,我们需要用到的:
字符集 | 字数 | Unicode 编码 |
---|---|---|
基本汉字 | 20902字 | 4E00-9FA5 |
基本汉字补充 | 38字 | 9FA6-9FCB |
扩展A | 6582字 | 3400-4DB5 |
扩展B | 42711字 | 20000-2A6D6 |
扩展C | 4149字 | 2A700-2B734 |
扩展D | 222字 | 2B740-2B81D |
康熙部首 | 214字 | 2F00-2FD5 |
部首扩展 | 115字 | 2E80-2EF3 |
兼容汉字 | 477字 | F900-FAD9 |
兼容扩展 | 542字 | 2F800-2FA1D |
PUA(GBK)部件 | 81字 | E815-E86F |
部件扩展 | 452字 | E400-E5E8 |
PUA增补 | 207字 | E600-E6CF |
汉字笔画 | 36字 | 31C0-31E3 |
汉字结构 | 12字 | 2FF0-2FFB |
汉语注音 | 22字 | 3105-3120 |
注音扩展 | 22字 | 31A0-31BA |
〇 | 1字 | 3007 |
数字0-9 | 10字 | 30-39 |
小写英文字母 | 26字 | 61-7a |
大写英文字母 | 26字 | 41-5a |
而汉字的Unicode范围为\u4E00-\u9FA5
。
这意味着:如果你要判断字是否为汉字,那么最基本只需要判断是否在这个区间即可。
代码实现✌️
最后,终于讲到大家期待的代码实现部分了。不过,相信大家看了上诉分析,应该都用思路了~~
统计中文
按刚刚所说,我们使用Unicode编码配合正则表达式进行中文字节统计:
\u4E00-\u9FA5
为中文Unicode编码段,所以使用正则表达式,匹配每个字是否为中文:
let iTotal = 0;
for (let i = 0; i < Words.length; i++) {
let c = Words.charAt(i);
//基本汉字
if (c.match(/[\u4e00-\u9fa5]/)) {
iTotal++;
}
//基本汉字补充
else if (c.match(/[\u9FA6-\u9fcb]/)){
iTotal++;
}
}
所以:
中文字数=
iTotal
统计英文和数字
for (let i = 0; i < Words.length; i++) {
let c = Words.charAt(i);
if (c.match(/[^\x00-\xff]/)) {
sTotal++;
}
else {
eTotal++;
}
if (c.match(/[0-9]/)) {
inum++;
}
}
这边解释一下:
/[^\x00-\xff]/
:匹配所有非双字节的字符。/[0-9]/
:匹配数字0到9
理论上,sTotal
包含:中文字
、中文全角字符(如:?。、,等)
。所以:
中文全角标点=
iTotal
-sTotal
数字=inum
- 字数=
inum
+iTotal
- 标点=
sTotal
-iTotal
- 字母=
eTotal
-inum
- 字符=
iTotal
* 2 +(sTotal - iTotal)
* 2 +eTotal
换成JS代码:
let hanzi, zishu, biaodian, zimu, shuzi, zifu;
//汉字
hanzi = iTotal;
//字数
zishu = (inum + iTotal);
//标点
biaodian = sTotal - iTotal;
//字母
zimu = (eTotal - inum);
//数字
shuzi = inum;
//字符
zifu = (iTotal * 2 + (sTotal - iTotal) * 2 + eTotal);
前端我们也写一下:
我建议在Vue内使用,可以注册为components
;当然,注册为组件的话,就改为一个函数,需要有返回值:
最后,进行使用:
以上,其实就是我在线工具箱的底层代码嗷。
总结📝
使用JavaScript,轻松前端进行字符和字数的统计。减轻后端压力。
并且,本方法使用正则表达和Unicode字符判断,理论上可以移植到任何代码平台(如:Python)。