前言:最近项目中客户要求只保留文本中的字母部分,比如将处理文本 [ 文本你 好 呀, PL-g;'.*o,o 121“‘2ds -> 你好呀PLgoods ]。使用如下Java代码可以达成目的,但是对于\\PL+这种非常规的正则表达式比较陌生,那么如果延伸下需求,比如要去除文本中的数字符号、货币符号、标点符号以及控制字符等可能就无能为力,始终停留在知其然而不知其所以然的状态。本人通过查阅资料结合个人理解整理成本篇博客,目标是记录下这种正则的本质,提供一种新的方式或手段来达成文本处理目的;

public static void main(String[] args) throws IOException {String contents = "你 好 呀, PL-g;'.*o,o 121“‘2ds";contents = contents.replaceAll("\\PL+","");System.out.println(contents);
}

1.1  unicode字符常识

首先明确一点计算机中显示的任何一个能正常显示的符号都算作一个unicode字符,unicode字符涵盖了各语言区域下出现的字母、数字、标点、空格换行、货币符号等;日常我们提及到unicode字符,更多地关注unicode字符编码(code point),其实与正则相关的还有另外三个属性:分别为Unicode Property、Unicode Block、Unicode Script。我们可以通过以下图片加强下认知,可以发现unicode字符的这三个属性分别从三个不同的角度来描述unicode字符

1.2  Unicode Block

按照编码去接划分Unicode字符,每个Unicode字符都有唯一归属的Unicode Block,各个区间彼此联系但互不相交;一般情况下同一种语言的字符通常落在同一区间内,所以Unicode Block可以粗略地表示某类语言的字符,可以通过Unicode块来查看详细的Block划分,简单Java示例如下。另外这个区间划分不太靠谱,比如涉及到全半角和不同语言区域下的标点时就需要具体确认到底在哪个区间下才可以使用,不要通过字面意思来断定,切记!

每个 Unicode Block 都对应一个连续的 Unicode 码值区间,U+0000 到U+FFFF 之间的字符一共划分为 105 个 Block,点此查看每个Block所包含的所有Unicode字符。使用时应该注意,Java 使用的 Unicode Block 是\p{In...}形式的,比如InCJK_Unified_Ideographs;而 .NET 使用的 Unicode Block 是\p{Is...}形式的,同时不包含下划线,比如IsCJKUnifiedIdeographs。

Java代码示例:

// CJK -> China Japanese Korea  兼容 CJK(中文、日文、韩文)统一表意字符
System.out.println("我".matches("\\p{InCJK_Unified_Ideographs}"));

1.3  Unicode Script

按照字符所属的书写系统来划分 Unicode 字符,比如\p{Greek}表示希腊语字符,\p{Han}表示汉语(中文字符)。它的写法类似 Unicode Block,只是名字的开头没有 Is 或者 In。由于Java目前不支持,所以就不演示了;

1.4  Unicode Property

按照字符的功能对Unicode进行分类,每个Unicode字符只能属于一个Unicode Property。语法类型/p{大类[小类]},小类可忽略。诸如:/pL、/pSc、/pPc等。从功能角度描述字符;比如有些字符是语言字母,有些用作标点符号,有些又来处理空格字符;需要注意的是它并不关心字符所属的语言,不在乎全角半角,不介意是中文还是英文,只关注这个字符的功能本身,即在不同语言区域下的功能是一致的;目前Java是支持Unicode Property的,前言部分谈及的需求就是利用了Java支持Unicode Property这个特性实现的,其它语言是否支持请自行查阅确认;

另外可以将/p -> /P,含义相反;比如/pL表示匹配各种语言区域下的字母,那么/PL表示匹配各种语言区域下的非字母内容,简单理解为/pL和/PL匹配内容截然相反,逻辑非的关系,如下一个简单DEMO体会下区别:

public static void main(String[] args) throws IOException {String contents = "你 好 呀, PL-g;'.*o,o 121“‘2ds";System.out.println("original -> " + contents);System.out.println("\\pL+ -> " + contents.replaceAll("\\pL+",""));System.out.println("\\PL+ -> " + contents.replaceAll("\\PL+",""));
}

每个 Unicode 字符都只能属于一个 Unicode Property。所有的Unicode Property 共分为7大类,30小类。大类的名字只有1个字母,小类的名字则不知1个字母,开头字母与所在大类的名字相同,小类包含的字符都属于它所在的大类。

Unicode Property 说明
\p{C} 不可见的控制字符和未使用的码值
  \p{Cc} ASCII 编码中 0x00 到 0x1F 或 Latin-1 编码中 0x80 到 0x9F 的控制字符
\p{Cf} 不可见的格式字符
\p{Co} 留作私用的码值
\p{Cs} UTF-16 编码中 surrogate pair 的一半
\p{Cn} 未指定的码值
\p{L} 各种语言中的字母
  \p{Ll} 具有大写形式的字母的小写形式
\p{Lt} 只有在单词首位才大写的字符
\p{L&} 等于Ll、Lu、Lt的组合
\p{Lo} 没有大小写形态的字母
\p{Lu} 具有小写字母的字母的大写形式
\p{M} 用来与其他字符结合的字符(声调、元音变化音等)
  ">\p{Mc} 与其他字符组合,并且会占用空间的字符(常见于东亚语言)
\p{Me} 需要成对出现的字符,比如圆括号、方括号
\p{Mn} 用来与其他字符结合,但并不占用额外空间的字符
\p{N} 各种书写系统中的数字字符
  \p{Nd} 各种书写系统中的 0~9 的字符
\p{Nl} 形如字符的数字,比如罗马数字
\p{No} 上标或者下标数字,或者是0~9之外的数字(不包括表一书写系统中的数字)
\p{P} 各种标点符号
  \p{Pd} 各种连字符号
\p{Ps} 成对但不同的符号的前半部分(包括英文括号、中文括号、书名号)
\p{Pe} 成对但不同的符号的后半部分(包括英文括号、中文括号、书名号)
\p{Pi} 成对但不同的符号的前半部分(比如单引号、双引号)
\p{Pf} 成对但不同的符号的后半部分(比如单引号、双引号)
\p{Pc} 类似下划线之类的标点字符
\p{Po} 除横线、括号、引号和连接符之外的任何标点符号
\p{S} 数字符号、货币符号
  \p{Sm} 数字符号
\p{Sc} 货币符号
\p{Sk} 由多个字符构成的组合字符
\p{So} 数字符号、货币符号和组合字符之外的符号字符
  \p{Z} 空白字符,或者不可见的字符
\p{Zs} 不可见但占用空间的空白字符
\p{Zl} 分行符 U+2028
\p{Zp} 分段符 U+2029

至此,相信大家应该对Java中采用支持Unicode Property的正则表达式有了一定的了解,回头再看如下代码时是不是就会觉得很简单了呢!

以上,完了,以便自己与后来者!

Java正则之Unicode属性匹配的那些事相关推荐

  1. Java正则的全量匹配和部分匹配

    一,前言 我们在用String.matches()的时候发现字符串中有能匹配的地方却返回为false.如: String abc = "regex.1234561";boolean ...

  2. java中a z正则表达式,Java正则字符类[a-zA-Z]匹配

    字符类[a-zA-Z]匹配从a到z或A到Z的任何字符. 示例 以下示例显示了字符类匹配的用法. package com.yiibai; import java.util.regex.Matcher; ...

  3. JAVA正则校验加减乘除,正则表达式匹配加减法算法

    搜索热词 通过键盘输入100以内正整数的加.减运算式,请编写一个程序输出运算结果字符串. 输入字符串的格式为:"操作数1 运算符 操作数2","操作数"与&qu ...

  4. java正则多条件表达式匹配提取

    提取字符串中的数字,不论是浮点数还是整数 String str = "20+10+20.158-(2200.125-80.23*325)+57";Pattern pattern = ...

  5. java正则匹配table_js正则匹配table tr

    js正则匹配table tr 我觉得比ijao简单,但是脑子就是转不过弯....请正则高手看看阿. 复制代码 代码如下: title title2 data1 data2       data1 da ...

  6. java正则匹配英文句号_「正则表达式」王国奇遇记

    第一回 初来乍到 NPC: "欢迎来到正则表达式的国度,勇士!这里的每一个人都使用正则表达式,我是这里的 NPC,每一个来到这里的人都将由我代为介绍正则世界的规则,至于能领悟到何种境界,就看 ...

  7. js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global)...

    js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global) 一.总结 1. ...

  8. Java正则匹配提取年月日字符串

    Java正则匹配提取年月日字符串 String string1="9999-9-99";Pattern p = Pattern.compile("(\\d{4})-(\\ ...

  9. Java正则匹配 以某个汉字开头和结束

    Java正则匹配 以某个汉字开头和结束 Java代码示意: public static void main(String[] args) {String str = "正则匹配测试" ...

最新文章

  1. spark_updateStateByKey
  2. ubuntu 安装RPM软件包
  3. ActiveMQ_安全配置(五)
  4. Shady 深度学习课程
  5. 模板:Link Cut Tree(LCT)
  6. spring学习(10):创建项目(自动装配)
  7. WINCE下I/O操作基础
  8. python发送邮箱_你知道怎么用Python发送邮件吗?
  9. 搭建主从数据库出现的错误 error connecting to master ‘slave@172.17.0.2:3306‘ - retry-time: 30 retries: 1
  10. Android DDMS的打开以及查看手机页面布局层次
  11. ActionScript 3 step by step (2) - 使用Trace()跟踪输出
  12. diolog js_js组件-js插件-jquery插件-dialog对话框弹层
  13. c语言getchar在哪个头文件_c语言入门(一)
  14. netty 多线程微盘_Netty多线程处理机制
  15. 三极管构成的流水灯电路分析
  16. 数据结构之线性表,这一篇就够了,吐血总结,建议收藏~~
  17. Mac制作windows10安装U盘
  18. 电脑开热点手机搜不到连不上
  19. C语言实现日历打印小程序
  20. Wallpaper Engine pkg壁纸文件提取工具

热门文章

  1. 【Linuxamp;Unix--open/close/write/read系统调用】
  2. 将语音搜索集成到Google Now中
  3. Binary Tree Preorder Traversal @leetcode
  4. [HTTP] Cookie
  5. react-组件状态机制(五)
  6. 7-46 最长对称子串 (25 分)
  7. 汉堡王什么汉堡好吃_汉堡王10元汉堡太好吃了,秒杀肯德基和麦当劳,一次吃两个...
  8. 剑指offer-JZ27 二叉树的镜像(C++,附思路)
  9. python获取文件夹里有什么文件+查看特定格式的文件
  10. es6 获取对象的所有值_前端开发必备 - ES6 新特性之 Set和Map数据结构