Javascript unicode字符串,中文字符,但没有标点符号



我正试图使用javascript废弃一个unicode字符串。所述字符串可以包含混合字符。示例:我的中文不好。我是意大利人。你知道吗?

最终,字符串可能包含-汉字-中文标点符号-ANSI字符和标点符号

我只需要留下汉字。有什么提示吗?

您可以在http://www.unicode.org/reports/tr38/#BlockListing或http://www.unicode.org/charts/。

如果你排除了兼容字符(不应该再使用的字符),以及笔划、部首和封闭的CJK字母和月份,下面应该涵盖它(我后来添加了单独的JavaScript等效表达式):

  • 中日韩统一象形文字(4E00-9FCC)[u4E00-u9FCC]
  • 中日韩统一象形文字扩展名A(3400-4DB5)[u3400-u4DB5]
  • 中日韩统一象形文字扩展名B(20000-2A6D6)[ud840-ud868][udc00-udfff]|ud869[udc00-uded6]
  • 中日韩统一象形文字扩展名C(2A700-2B734)ud869[udf00-udfff]|[ud86a-ud86c][udc00-udfff]|ud86d[udc00-udf34]
  • 中日韩统一象形文字扩展名D(2B840-2B81D)ud86d[udf40-udfff]|ud86e[udc00-udc1d]
  • 中日韩兼容象形文字(F900-FA6D/FA70-FAD9)中的12个字符,但实际上是中日韩统一表意文字[uFA0EuFA0FuFA11uFA13uFA14uFA1FuFA21uFA23uFA24uFA27-uFA29]

。。。因此,获取中文字符的正则表达式是:

/[u4E00-u9FCCu3400-u4DB5uFA0EuFA0FuFA11uFA13uFA14uFA1FuFA21uFA23uFA24uFA27-uFA29]|[ud840-ud868][udc00-udfff]|ud869[udc00-uded6udf00-udfff]|[ud86a-ud86c][udc00-udfff]|ud86d[udc00-udf34udf40-udfff]|ud86e[udc00-udc1d]/

事实上,由于有许多CJK(中日韩)字符,Unicode被扩展以处理更多的字符;基本多语言平面";(称为"星形"字符),并且由于CJK统一象形文字扩展B-D是这样的星形字符的示例,这些扩展具有更复杂的范围,因为它们必须在UTF-16系统(如JavaScript)中使用代理对进行编码。代理项对由一个高代理项和一个低代理项组成,这两个代理项本身都无效,但当它们连接在一起时,会形成一个实际的单个字符,尽管它们的字符串长度为2)。

虽然出于替换的目的,将其表示为非中文字符(用空字符串替换)可能更容易,但我提供了中文字符的表达式,以便在需要添加或从块中删除时更容易跟踪。

2017年9月更新

作为ES6,可以通过使用";u〃;标志以及带有括号的新转义序列内部的代码点,例如/^[u{20000}-u{2A6D6}]*$/u表示"0";CJK统一象形文字扩展名B";。

注意,Unicode也已经发展到包括";中日韩统一象形文字扩展名E";([u{2B820}-u{2CEAF}])和";中日韩统一象形文字扩展名F";([u{2CEB0}-u{2EBEF}])。

对于ES2018,Unicode属性转义似乎能够进一步简化事情。每http://2ality.com/2017/07/regexp-unicode-property-escapes.html,看起来将能够做到:

/^(p{Block=CJK Unified Ideographs}|p{Block=CJK Unified Ideographs Extension A}|p{Block=CJK Unified Ideographs Extension B}|p{Block=CJK Unified Ideographs Extension C}|p{Block=CJK Unified Ideographs Extension D}|p{Block=CJK Unified Ideographs Extension E}|p{Block=CJK Unified Ideographs Extension F}|[uFA0EuFA0FuFA11uFA13uFA14uFA1FuFA21uFA23uFA24uFA27-uFA29])+$/u

作为来自的较短别名http://unicode.org/Public/UNIDATA/PropertyAliases.txt和http://unicode.org/Public/UNIDATA/PropertyValueAliases.txt也可以用于这些块,您可以将其缩短为以下内容(如果需要,还可以将下划线更改为空格或大小写):/^(p{blk=CJK}|p{blk=CJK_Ext_A}|p{blk=CJK_Ext_B}|p{blk=CJK_Ext_C}|p{blk=CJK_Ext_D}|p{blk=CJK_Ext_E}|p{blk=CJK_Ext_F}|[uFA0EuFA0FuFA11uFA13uFA14uFA1FuFA21uFA23uFA24uFA27-uFA29])+$/u

如果我们想提高可读性,我们可以使用命名的捕获组来记录错误标记的兼容性字符(请参见http://2ality.com/2017/05/regexp-named-capture-groups.html):

/^(p{blk=CJK}|p{blk=CJK_Ext_A}|p{blk=CJK_Ext_B}|p{blk=CJK_Ext_C}|p{blk=CJK_Ext_D}|p{blk=CJK_Ext_E}|p{blk=CJK_Ext_F}|(?<CJKFalseCompatibilityUnifieds>[uFA0EuFA0FuFA11uFA13uFA14uFA1FuFA21uFA23uFA24uFA27-uFA29]))+$/u

看起来http://unicode.org/reports/tr44/#Unified_Ideograph就像";统一象形文字";属性(别名"UIdeo")涵盖了我们所有的统一表意文字,不包括符号/标点符号和兼容字符,如果您不需要从上面挑选,以下可能就是您所需要的:

/^p{Unified_Ideograph=yes}*$/u

或缩写:

/^p{UIdeo=y}*$/u

2023年4月更新

JavaScript似乎还没有支持Block/blk作为可接受的属性别名之一:请参阅https://tc39.es/ecma262/multipage/text-processing.html#table-当前允许的非二进制属性的非二进制unicode属性。

对于Chrome 64、Firefox 78、Safari 11.1和Edge 79,测试字符串是否为汉字的最简单正则表达式是/p{Script=Han}/up{}指定Unicode属性转义,Script=Han表达式匹配script属性为Han(中文)的任何字符,u标志允许使用正则表达式中的Unicode功能,例如这些属性转义。

所以你可以从这样的字符串中过滤所有的非中文字符:

console.log(
"hello! 42 我的中文不好。我是意大利人。你知道吗?"
.split("")
.filter(char => /p{Script=Han}/u.test(char))
.join("")
);

Script属性名称也可以缩写为/p{sc=Han}/u

复制粘贴解决方案。使用ES6的unicode标志。所有当前扩展名,直到扩展名F和象形文字。

const character_xp = new RegExp(String.raw`
[u{FA0E}u{FA0F}u{FA11}u{FA13}u{FA14}u{FA1F}u{FA21}u{FA23}u{FA24}u{FA27}-u{FA29}]
|[u{4E00}-u{9FCC}]
|[u{3400}-u{4DB5}]
|[u{20000}-u{2A6D6}]
|[u{2A700}-u{2B734}]
|[u{2B740}-u{2B81D}]
|[u{2B820}-u{2CEAF}]
|[u{2CEB0}-u{2EBEF}]
`.replace(/s+/g, ''), "u")

与其发明自己的解决方案,不如使用unicode数据模块(确切地说是它生成的模块之一),它本质上是UnicodeData.txt数据库的javascript接口(类似于python中的UnicodeData标准模块,如果它能让你大吃一惊的话)。

最新更新