js 中文字符串判断(根据 unicode 编码区间判断)
发布于 8 年前 作者 alsotang 11872 次浏览 来自 分享

地址在:https://github.com/alsotang/is-chinese

Build Status

install

for npm

$ npm install is-chinese

for browser

<script src="ischinese.js"></script>

A UMD bundle. If no module system is found, window.ischinese would be assigned.

description

Chinese range is based on: https://en.wikipedia.org/wiki/CJK_Unified_Ideographs

example

var isChinese = require('..')
isChinese('中国').should.true();
isChinese('中国ss').should.false();
isChinese('ss').should.false();
isChinese("\uD842\uDFB7").should.true();

benchmark

Node 4.2.1

       8,643,328 op/s » isChinese("扁担宽,板凳长,扁担想绑在板凳上。")
      17,484,791 op/s » isChinese("ss扁担宽,板凳长,扁担想绑在板凳上。")

license

MIT

22 回复

能否增加简繁体的判断? isTradionalChinese 简繁字体混合判断?

should.false()没见过这种写法呢。。

来自酷炫的 CNodeMD

@lingmm 符合文档的啊。。

@SoaringTiger 目前是混合判断。简繁之间经常混用,没法准确区分啊。而且一些用户喜欢用繁体字,网站敢直接干掉他们吗?

额 。。。之前都是参照结巴分词里的正则判断。好像判断文字,符号,是否包含的需求都不太一样。

顺便问下,为啥不用正则要自己写循环呢?

@reverland 你觉得循环快还是正则快?

@alsotang 应该差不多?额。。。发现都不支持unicode regexp还。。。

@alsotang 。。。本来觉得没有unicode regexp会慢些,跑了下你看看测试是不是有问题。。。

https://jsperf.com/ischinese-loop-vs-regexp

@reverland http://es6.ruanyifeng.com/#docs/regex

没看懂你说的 unicode 之类的东西。。。你看看上面的链接

速度来说,我看结果也是 loop 比较快啊。

@alsotang

不一定是loop比较快。我开始测试用例是如下写的:

// testcase 1
isChinese("你好啊");
isChinese("你好啊s");
// testcase 2
isChineseReg("你好啊");
isChineseReg("你好啊s");

正则都会快一些。很奇怪所以把测试拆分了

关于unicode regexp

我说unicode只是指u标志,开始测试想直接写成ES6的正则

reg = /^[\u4e00-\u9fff\u3400-\u4dbf\u{20000}-\u{2a6df}\u{2a700}-\u{2b73f}\u{2b740}-\u{2b81f}\u{2b820}-\u{2ceaf}\uf900-\ufaff\u3300-\u33ff\ufe30-\ufe4f\uf900-\ufaff\u{2f800}-\u{2fa1f}]+$/mu

后来发现根本没哪里支持(或者我哪里写错了?)。。。于是用https://mothereff.in/regexpu 翻译成ES5的

 reg = /^(?:[\u3300-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\uFE30-\uFE4F]|[\uD840-\uD868\uD86A-\uD872][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD873[\uDC00-\uDEAF]|\uD87E[\uDC00-\uDE1F])+$/m

某次的结果

Screenshot from 2015-12-08 16:02:44.png

补充isChineseReg函数

    reg = /^(?:[\u3300-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\uFE30-\uFE4F]|[\uD840-\uD868\uD86A-\uD872][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD873[\uDC00-\uDEAF]|\uD87E[\uDC00-\uDE1F])+$/m
    
    function isChineseReg(str) {
      return reg.test(str);
    }

@reverland untitled1.png

我这里是这样的。

@reverland 靠你是 firefox 啊

@alsotang >_< 来个chromium 在我这里都差不多。。。卧槽你机器真好

Screenshot from 2015-12-08 22:02:31.png Screenshot from 2015-12-08 22:07:16.png

@reverland 13年的 macbook air。。。。没多好。。

@alsotang codePointAt 微信中的qq浏览器不支持。。。

@reverland 我用了 polyfill 的,我这个库可以支持吧

@alsotang 嗯。。。只是写测试时没注意。在想为啥perf结果不一样,然而并没啥思路。

想起之前welefen讲到过v8提供的es6特性执行效率,往往还比不上babel翻译的代码运行效率。。。我当时都震惊了。。。一直没怎么接触transpiler就是觉得调试不方便和性能会差。。。 firefox的Map和Set实现者谈论hash tables that track insertion order in JS时所提到的令人惊讶的benchmark和理论分析的差异。。。 诸如此类 越来越觉得,嗯。。。再也不能凭借直觉去判断效率,分析未必靠谱,benchmark也未必能说明什么。。。所以。。。

好吧,效率对我没这么重要,这些问题让需要的人去探索,我还是玩去吧,233。。。

@reverland 当时我写这个地方的时候没有考虑效率,只是觉得循环比较直观,就这么写了。而且我也相信循环一定不是一种慢的方式,就没怎么注意这里的效率。

感谢两位,我这里效率也不是主要问题,不过这个库确实好用!

@xieaolin 擦。。这个库我怎么 readme 全部写的是英文。。。

回到顶部