JS:用正则表达式统计英文单词和GBK汉字个数
本帖最后由 马黑黑 于 2023-1-23 08:16 编辑先说GBK汉字,因为GBK汉字好处理。
GBK汉字共 20,902 个,从“一”开始到“龥”结束,在Unicode编码里连在一起。正则表达式可以用最简单的 [一-龥] 来表示:
let reg_hanz = /[一-龥]/g;
g 开关是全局开关,这是必须的,否则只检测一个汉字,@小辣椒 给作者发稿费就赚大了。
那么,待匹配字符串 str 里是否有含有GBK汉字,我们可以用 test 方法进行检测:
reg_hanz.test(str)
如果 str 里有GBK汉字,上述语句返回 true,反之返回 false。
接着说英文单词。英文单词应该有如下几种常见的结构,都被视为一个单词:
① pencil : 由纯字母组成的单词
② pencil-box :由连接符 - 连接而成的纯字母组合词
③ 16-year-old :由连接符 - 连接而成的数字、字母组合词
④ it's :由分隔符 ' 实现的缩写词
我们用 \b\w+\b 匹配第一种结构的单词没问题:\b 是单词边界,\w包含所有字母(外加数字下划线);匹配第二种有问题:符号 - 会被视为单词边界,pencil-box 会被视为两个单词;匹配第三种更有问题,会被视为三个单词;匹配第四种道理和匹配第二种的情况一样。
解决思路是:先用 \b\w+\b去匹配 str,得到一个总数,这个总数肯定多于实际的单词个数。然后再去检索单词中的 - 和 ' 出现的次数,这个分两步走,一步是只出现一次- 或 ‘ 的,另一步是 出现两个 - 的,也就是统计单词中出现过 - 或 ' 、两个 - 的,前面得到的总数减去它们的出现次数,就基本得到单词的个数了,不一定百分百准确,因为也许还有我们罗列不到的单词组成样式或是因为匹配规则设计的不好,但大致是八九不离十了,@樵歌给作者发稿费大约只赚不亏。
以上是实现思路,示范放在下楼,欢迎有兴趣的朋友检验。
本帖最后由 马黑黑 于 2023-1-22 21:26 编辑 <br /><br /><style>
#txtbox {
width: 740px;
height: 520px;
padding: 12px;
display: block;
margin: auto;
}
</style>
<textarea id="txtbox"></textarea>
<p><br><input id="okey" type="button" value="统计"/> <span id="result" ></span>
<script>
let calcwords = (str) => {
let reg_word = /\b\w+\b/gm,
reg_link = /\w+[-']\w+/g,
reg_links = /\w+-\w+-\w+/g,
reg_hanz = /[一-龥]/g;
let num_word = 0,
num_link = 0,
num_links = 0,
num_hanz = 0;
if (reg_word.test(str)) num_word = str.match(reg_word).length;
if (reg_link.test(str)) num_link = str.match(reg_link).length;
if(reg_links.test(str))num_links = str.match(reg_links).length;
console.log(reg_link.test(str));
if (reg_hanz.test(str)) num_hanz = str.match(reg_hanz).length;
return {
en: num_word - num_link - num_links,
cn: num_hanz,
};
};
okey.onclick = () => {
let a = calcwords(txtbox.value);
result.innerText = `英文单词 ${a.en} | 汉字 ${a.cn}`;
}
</script> 本帖最后由 马黑黑 于 2023-1-22 21:26 编辑
二楼代码:
<style>
#txtbox {
width: 740px;
height: 520px;
padding: 12px;
display: block;
margin: auto;
}
</style>
<textarea id="txtbox"></textarea>
<p><br><input id="okey" type="button" value="统计"/> <span id="result" ></span>
<script>
let calcwords = (str) => {
let reg_word = /\b\w+\b/gm,
reg_link = /\w+[-']\w+/g,
reg_links = /\w+-\w+-\w+/g,
reg_hanz = /[一-龥]/g;
let num_word = 0,
num_link = 0,
num_links = 0,
num_hanz = 0;
if (reg_word.test(str)) num_word = str.match(reg_word).length;
if (reg_link.test(str)) num_link = str.match(reg_link).length;
if(reg_links.test(str))num_links = str.match(reg_links).length;
console.log(reg_link.test(str));
if (reg_hanz.test(str)) num_hanz = str.match(reg_hanz).length;
return {
en: num_word - num_link - num_links,
cn: num_hanz,
};
};
okey.onclick = () => {
let a = calcwords(txtbox.value);
result.innerText = `英文单词 ${a.en} | 汉字 ${a.cn}`;
}
</script>
虽说还不是很严谨,代码也没做优化,但好歹核心功能是健壮的也是基本靠谱的 俺给你拜年啦!祝你新春快乐、幸福安康! 小黑新年好{:4_176:} 樵歌 发表于 2023-1-23 07:58
小黑新年好
为新年干杯 庶民来了 发表于 2023-1-23 07:14
俺给你拜年啦!祝你新春快乐、幸福安康!
{:4_194:} 马黑黑 发表于 2023-1-23 08:13
美酒、蜡烛、大餐,多么美妙的新年!唯独就缺你的钱包!朋友,新年快乐! 庶民来了 发表于 2023-1-23 08:49
美酒、蜡烛、大餐,多么美妙的新年!唯独就缺你的钱包!朋友,新年快乐!
{:4_173:} 去试了一下,原来阿拉伯数字也被统计在英文单词里。 这个好,可以用来检验字数了,省得每次为了查字数还得专门去打开word了{:4_173:} 红影 发表于 2023-1-23 10:51
这个好,可以用来检验字数了,省得每次为了查字数还得专门去打开word了
Word也快的,还支持正则查找 红影 发表于 2023-1-23 10:49
去试了一下,原来阿拉伯数字也被统计在英文单词里。
这里是这样,也是可以接受的 黑黑啥都会,这种我从来没有想过这种操作{:4_177:} 小辣椒 发表于 2023-1-23 11:32
黑黑啥都会,这种我从来没有想过这种操作
玩玩 马黑黑 发表于 2023-1-23 11:15
Word也快的,还支持正则查找
这个更好啊,因为是花潮人黑黑的作品,用着更开心{:4_199:} 马黑黑 发表于 2023-1-23 11:16
这里是这样,也是可以接受的
嗯嗯,反正汉字都被统计到了就好{:4_173:} 红影 发表于 2023-1-23 15:46
嗯嗯,反正汉字都被统计到了就好
很久以前我做过字数统计,都是集成在程序里,没有用到正则和JS,用的是遍历。做这些查阅过一些资料,但时间隔得太久,有好多规范现在印象不深。 红影 发表于 2023-1-23 15:45
这个更好啊,因为是花潮人黑黑的作品,用着更开心
这个是实验性质的,也许准确