Java正则表达式进阶教程之构造方法
2013-02-09 11:47
316 查看
原文发于http://blog.thihy.info/post/119,转载请注明出处。
本文是在学习正则表达式过程中整理的,虽然冠以“教程”,但实际上应该算是学习笔记。整篇文章需要对正则有一定的理解。。如果有啥写得不对的,或者写得不够清楚的,欢迎大家留言讨论。
正则表达式(Regular Expression)是高效的、便捷的文本处理工具,能够快速查询符合某种规范的文本。
例如:
目前正则表达式被众多工具所支持,比如egrep、sed、perl、ruby、Java、C#、python、Tcl等,不同的工具下,正在表达式的范式可能会有略微的差别,执行引擎也可能不同。目前,正则引擎主要有:DFA, 传统型NFA, POSIX NFA, DFA/NFA混合。本文主要介绍Java正则表达式,它的引擎属于传统型NFA。
Java正则支持Unicode,它在适当的时候,会使用
Java中的正则表达式的构造方法可以看Pattern的javadoc文档。
对于可见字符,可以直接编写,这没啥难点。对于其它难以描述的字符,Java提供了一些表示方法。
Java执行使用
反斜线字符
制表符 (‘\u0009′)
新行(换行) 符 (‘\u000A’)
回车符 (‘\u000D’)
换页符 (‘\u000C’)
报警(bell)符 (‘\u0007′)
转义符 (‘\u001B’)
垂直制表符 (‘\u000B’)
Java可以使用
Java中,八进制表示必须以\0开始(防止与反向引用混淆),这点可能与其他工具不同(某些工具有规则来区分反向引用和八进制)。\0后面的部分最多只能有3个数字,而n必须在区间[0,7]内,m必须在[0,3]内,所以最大表示\0377。
十六进制后面必须是两个十六进制字符,也即h必须是0~9,a-f或A-F。\x00和\xff都是合法的,但是\xa,\x0ab,\x1g都是不合法的。
Unicode转义的形式与十六进制类似,只是后面必须是四个六进制字符。
行结束符是用来标记输入字符序列的行结尾,可能有一个或两个字符。在Java中,行结束符包括:
新行(换行)符 (‘\n’)
后面紧跟新行符的回车符 (“\r\n”)
单独的回车符 (‘\r’)
下一行字符 (‘\u0085′)
行分隔符 (‘\u2028′)
段落分隔符 (‘\u2029)
如果启用了UNIX_LINES模式,则新行符(即’\n’)是惟一识别的行结束符。
只有启用DOTALL标志,正则表达式中的点号(即’.')才会匹配行结束符。
默认情况下,正则表达式^和$会忽略行结束符,仅分别与整个输入序列的开头和结尾匹配。如果激活 MULTILINE 模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配。处于 MULTILINE 模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配。
字符类的形式是
字符类集合运算
字符类可以进行补集、并集(隐式)、交集和差集的运算。所有的集合运算都必须在字符类内部实现。
补集 如果字符类中以
并集 可以在字符类中以字符类的方式来进行并集操作,比如对于[123456],可以表示为[123[456]]、[[123][456]、[[1][2][3][4][5][6]]、[[1[2]][3][4[5]6]]。并集操作时隐式的,没有特别的操作符,只需要按次序排在一起就OK了。
交集 交集操作可以保留两个字符类的共同部分,它要求两个字符类之间添加交集运算符
差集 Java本身不支持差集元算,但是通过交集+补集的形式来实现。比如[[0-9] && [^3-5]]等价于[0-26-9]。同样,也可以通过环视功能来模拟差集,比如
Java在解析字符类时,会按照如下的次序依次执行:
字面值转义 \x
分组 [...]
范围 a-z
并集 [a-e][i-u]
交集 [a-z&&[aeiou]]
补集 [^...]
点号可以用来匹配除了行结束符之外的任意字符。但是,如果启用了DOTALL标志,则可以匹配行结束符。
Java预定义了如下几种字符组,可以很方便地使用。
PropOrBlock包括字符属性(Char Property)和区块(Block)。区块必须以
区块的定义在
部分Unicode区块列表(查看WIKI) 属性说明
基本的POSIX字符属性表(查看标准定义) 属性说明
本文是在学习正则表达式过程中整理的,虽然冠以“教程”,但实际上应该算是学习笔记。整篇文章需要对正则有一定的理解。。如果有啥写得不对的,或者写得不够清楚的,欢迎大家留言讨论。
概述
正则表达式(Regular Expression)是高效的、便捷的文本处理工具,能够快速查询符合某种规范的文本。例如:
[0-9]{3}可以匹配3位数字,
[a-z]{3}则可以匹配3个小写字母。
目前正则表达式被众多工具所支持,比如egrep、sed、perl、ruby、Java、C#、python、Tcl等,不同的工具下,正在表达式的范式可能会有略微的差别,执行引擎也可能不同。目前,正则引擎主要有:DFA, 传统型NFA, POSIX NFA, DFA/NFA混合。本文主要介绍Java正则表达式,它的引擎属于传统型NFA。
Java正则支持Unicode,它在适当的时候,会使用
java.lang.Character.codePointAt(CharSequence seq, int index)获取
Code Point,而不是char。
构造方法
Java中的正则表达式的构造方法可以看Pattern的javadoc文档。
字符
对于可见字符,可以直接编写,这没啥难点。对于其它难以描述的字符,Java提供了一些表示方法。
字符缩略表示法
Java执行使用\x来代表特殊的含义,有:
\\
反斜线字符
\t
制表符 (‘\u0009′)
\n
新行(换行) 符 (‘\u000A’)
\r
回车符 (‘\u000D’)
\f
换页符 (‘\u000C’)
\a
报警(bell)符 (‘\u0007′)
\e
转义符 (‘\u001B’)
\v
垂直制表符 (‘\u000B’)
控制字符: \cchar
Java可以使用\cchar匹配控制字符。其中
char的值为
64 ^ 控制字符,比如对于退格符(‘
\b‘),其ASCII码为8,则
char为
64 ^ 8 = 72,也即
H(H的ASCII码为72)。简单地,对于ASCII码小于64的控制字符,
char为控制字符的ASCII码加上64。
八进制表示:\0n
,
\0nn
, \0mnn
Java中,八进制表示必须以\0开始(防止与反向引用混淆),这点可能与其他工具不同(某些工具有规则来区分反向引用和八进制)。\0后面的部分最多只能有3个数字,而n必须在区间[0,7]内,m必须在[0,3]内,所以最大表示\0377。
十六进制表示:\xhh
十六进制后面必须是两个十六进制字符,也即h必须是0~9,a-f或A-F。\x00和\xff都是合法的,但是\xa,\x0ab,\x1g都是不合法的。
Unicode转义:\uhhhh
Unicode转义的形式与十六进制类似,只是后面必须是四个六进制字符。
行结束符
行结束符是用来标记输入字符序列的行结尾,可能有一个或两个字符。在Java中,行结束符包括:新行(换行)符 (‘\n’)
后面紧跟新行符的回车符 (“\r\n”)
单独的回车符 (‘\r’)
下一行字符 (‘\u0085′)
行分隔符 (‘\u2028′)
段落分隔符 (‘\u2029)
如果启用了UNIX_LINES模式,则新行符(即’\n’)是惟一识别的行结束符。
只有启用DOTALL标志,正则表达式中的点号(即’.')才会匹配行结束符。
默认情况下,正则表达式^和$会忽略行结束符,仅分别与整个输入序列的开头和结尾匹配。如果激活 MULTILINE 模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配。处于 MULTILINE 模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配。
字符类
字符类: [...]
字符类的形式是[...],其内部可以是若干字符,也可以是一个字符范围。比如[a]表示匹配a字符,[a-z]表示匹配所有小写的英文字母。字符范围中的字符可以是Unicode字符,并且不要求是同一类的,也即
[a-}]也是可以的,甚至是
[a-星]。
字符类集合运算
字符类可以进行补集、并集(隐式)、交集和差集的运算。所有的集合运算都必须在字符类内部实现。
补集 如果字符类中以
^开头,则表示是一个补集。比如[^a]表示匹配不是a的所有字符,这与[a^]是不同的,后者表示匹配a字符或^字符。既然是补集,那么需要明确全集是什么。由于Java是支持Unicode的,所以全集是所有的Unicode字符。也即[^a]可以匹配汉字字符。注:很多书籍上(包括JavaDoc)都没有谈到补集的概念,而是作为基本的字符类,但我觉得成为补集操作更加便于理解。
并集 可以在字符类中以字符类的方式来进行并集操作,比如对于[123456],可以表示为[123[456]]、[[123][456]、[[1][2][3][4][5][6]]、[[1[2]][3][4[5]6]]。并集操作时隐式的,没有特别的操作符,只需要按次序排在一起就OK了。
交集 交集操作可以保留两个字符类的共同部分,它要求两个字符类之间添加交集运算符
&&。例如[[1-5]&&[3-9]]等价于[3-5]。通过环视功能可以模拟交集运算,比如
(?=[1-5])[3-9]和
[3-9](?<=[1-5])都等价于[3-5]。
差集 Java本身不支持差集元算,但是通过交集+补集的形式来实现。比如[[0-9] && [^3-5]]等价于[0-26-9]。同样,也可以通过环视功能来模拟差集,比如
(?![3-5])[0-9]和
[0-9](?<![3-5])都等价于[0-26-9]。
Java在解析字符类时,会按照如下的次序依次执行:
字面值转义 \x
分组 [...]
范围 a-z
并集 [a-e][i-u]
交集 [a-z&&[aeiou]]
补集 [^...]
点号:.
点号可以用来匹配除了行结束符之外的任意字符。但是,如果启用了DOTALL标志,则可以匹配行结束符。
字符类简记法:
Java预定义了如下几种字符组,可以很方便地使用。\d数字:[0-9]
\D非数字:[^0-9]
\s空白字符:[ \t\n\x0B\f\r] (注意第一个字符是空格)
\S非空白字符:[^\s]
\w单词字符:[a-zA-Z_0-9]
\W非单词字符:[^\w]
Unicode属性和区块:\p{PropOrBlock
、\P{PropOrBlock
\p{PropOrBlock表示匹配符合PropOrBlock的所有字符,大写的
\P{PropOrBlock则匹配不符合PropOrBlock的所有字符。
PropOrBlock包括字符属性(Char Property)和区块(Block)。区块必须以
In开头,字符属性可以以
Is开头(可选)。Unicode
区块的定义在
java.lang.Character.UnicodeBlock,具体可以查看Unicode标准。字符属性的定义在
java.util.regex.Pattern.CharPropertyNames。
部分Unicode区块列表(查看WIKI) 属性说明
\p{InBASIC_LATIN} | Basic Latin |
\p{InCJK_COMPATIBILITY} | 中日韩兼容文字 |
更多请查看JavaDoc |
\p{ASCII} | ASCII字符: 0×00~0x7F |
\p{Lower} | 小写字母([a-z]) |
\p{Upper} | 小写字母([A-Z]) |
\p{Punct} | ASCII标点符号 |
\p{Alpha} | ASCII字母([a-zA-Z]) |
\p{Digit} | 数字([0-9] |
\p{Alnum} | ASCII字母和数字: [a-zA-Z0-9]) |
\p{Graph} | ASCII可打印(可见)字符: [\p{Alnum}\p{Punct}] |
\p{Blank} | ASCII Blank字符(空格和Tab字符) |
\p{Cntrl} | ASCII控制字符([\x00-\x1F\x7F]) |
\p{Print} | 可打印字符(0×20~0x7E) |
\p{Space} | ASCII Space字符([ \t\n\x0B\f\r]) |
\p{XDigit} | ASCII十六进制字符([0-9a-fA-F]) |
相关文章推荐
- Java正则表达式进阶教程之构造方法
- Java正则表达式进阶教程之构造方法
- JavaDay09--Notes(集合的框架与toString方法+正则表达式的元字符)
- 使用JS中的exec()方法构造正则表达式验证
- Java正则表达式进阶(二):简单查询域名的Whois信息
- Java正则表达式实例教程
- Java语言入门教程(十三):Java语言中继承中的构造方法问题
- 特殊字符导致用正则表达式进行字符串替换失败,Java replaceAll()方法报错Illegal group reference
- Java 正则表达式(来自菜鸟教程)
- JAVA中String对象split方法注意事项(切记其中的正则表达式)
- Java正则表达式教程
- Java正则表达式教程
- JAVA正则表达式实例教程(转帖收藏)
- Java正则表达式详解-JSP教程,Java技巧及代码
- JAVA中正则表达式匹配,替换,查找,切割的方法
- Java基于正则表达式获取指定HTML标签指定属性值的方法
- Java正则表达式判断邮箱地址数组,冒泡排序,String的方法
- Java进阶(九)正则表达式
- Java正则表达式中 matcher.find()方法的理解
- java使用正则表达式方法和正则表达式大全