【Java】java.util.Pattern详述

java.util.Pattern详述

这里完全按照JDK1.8 API文档的顺序来书写。

  • 类声明
  • 常用正则匹配总结
  • 反斜杠、转义和引号
  • 字符类
  • 行结束符
  • 分组和捕获
  • Unicode支持
  • 与Perl 5比较
  • 变量
  • 方法

类声明

public final class Pattern
extends Object
implements Serializable

一个编译好的正则表达式。正则表达式写成String的形式,在使用之前应该通过编译(compiled)创建Pattern实例,这个实例用来创建可以对任意字符序列进行匹配的Matcher对象,多个Matcher对象使用同一个Pattern实例。

下面是一个典型的例子:

Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();

注意上面是用Matcher的matches方法进行的匹配。实际上Pattern也有一个matches方法,可以实现与上面的例子相同的效果。但是如果这样用,那么Pattern就不能便捷地重用了。Pattern实例是不可变的,并且支持并发和多线程安全,而Matcher就不是这样。

boolean b = Pattern.matches("a*b", "aaaaab");

常用正则匹配总结

  • 字符转义
转义字符匹配内容
x字符x
\\反斜杠
\0n八进制0n字符(0 <= n <= 7)
\0nn八进制0nn字符(0 <= n <= 7)
\0mnn八进制0mnn字符(0 <= m <= 3, 0 <= n <= 7)
\xhh十六进制0xhh字符
\xhhhh十六进制0xhhhh字符
\x{h…h}十六进制0xh…h字符(字符范围在字符集最大值和最小值之间)
\t制表符字符(‘\u0009’)
\n换行符(‘\u000A’)
\r回车符(‘\u000D’)
\f换页符(‘\u000C’)
\a报警(bell)字符(‘\u0007’)
\e转义符(‘\u001B’)
\cxx指定的 ASCII 控件字符
  • 字符类
字符类匹配内容
[abc]a或b或c
[^abc]除了a、b、c
[a-zA-Z]任意一个英文字母(大写或小写均可)
[a-d[m-p]]相当于[a-dm-p],在a到d或m到p范围内的小写英文字母(包括边界)
[a-z&&[def]]相当于[a-z]集与[def]集相交,只能是d、e、f中的一个
[a-z&&[^bc]]相当于[a-z]集减去[bc]集,即[ad-z],小写英文字母且不为b或c
[a-z&&[^m-p]]相当于[a-z]集减去[m-p]集,即[a-lq-z]
  • 预定义的字符类
字符匹配内容
.任意字符(可能不匹配行结束符)
\d匹配数字[0-9]
\D匹配非数字[^0-9]
\h一个水平空白字符[ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]
\H匹配非水平空白字符[^\h]
\s一个空白字符[ \t\n\x0B\f\r]
\S匹配非空白字符[^\s]
\v一个垂直空白字符[\n\x0B\f\r\x85\u2028\u2029]
\V匹配非垂直空白字符[^\v]
\w单词字符[a-zA-Z_0-9],即大小写字母数字下划线集
\W非单词字符[^\w]
  • POSIX 字符类 (仅US-ASCII)
字符匹配内容
\p{Lower}小写字母集[a-z]
\p{Upper}大写字母集[A-Z]
\p{ASCII}所有ASCII码[\x00-\x7F]
\p{Alpha}所有大小写字母[\p{Lower}\p{Upper}]
\p{Digit}数字集[0-9]
\p{Alnum}大小写字母和数字集[\p{Alpha}\p{Digit}]
\p{Punct}符号集!”#$%&’()*+,-./:;<=>?@[]^_`{
\p{Graph}可见字符:大小写字母+数字+符号集[\p{Alnum}\p{Punct}]
\p{Print}可打印字符:[\p{Graph}\x20]
\p{Blank}空格或者制表符[ \t]
\p{Cntrl}控制字符[\x00-\x1F\x7F]
\p{XDigit}十六进制用到的字符[0-9a-fA-F]
\p{Space}空白字符[ \t\n\x0B\f\r]
  • java.lang.Character 类 (简单的 java 字符类型)
字符匹配内容
\p{javaLowerCase}相当于java.lang.Character.isLowerCase()
\p{javaUpperCase}相当于java.lang.Character.isUpperCase()
\p{javaWhitespace}相当于java.lang.Character.isWhitespace()
\p{javaMirrored}相当于java.lang.Character.isMirrored()
  • 用于 Unicode 脚本(script)、 块、 类别和二进制属性的类
字符匹配内容
\p{IsLatin}是否属于拉丁字符集(脚本)
\p{InGreek}是否是希腊单词(块)
\p{Lu}大写字母(类别)
\p{Sc}货币符号
\P{InGreek}不能使希腊语的任意字符
[\p{L}&&[^\p{Lu}]]不能是大写字母的任意字母
  • 定位匹配
字符匹配内容
^句首标志
$句尾标志
\b单词字符边界,意味着匹配必须在\w和\W之间的边界上
\B匹配位置不能是单词字符边界
\G上一个匹配结束的位置
\Z字符串的末尾且在\n之前
\z字符串的末尾
  • 换行符匹配
字符匹配内容
\R任意Unicode换行符,相当于\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
  • 贪婪匹配
字符匹配内容
X?匹配X一次或者零次
X*匹配X零次或者多次
X+匹配X一次或者多次
X{n}匹配X n次
X{n,}匹配X至少n次
X{n,m}匹配X至少n次,至多m次
  • 不情愿匹配(尽量不贪婪)
    这个匹配和贪婪匹配的匹配规则一样,但是希望匹配次数尽可能少
字符匹配内容
X??匹配X一次或者零次
X*?匹配X零次或者多次
X+?匹配X一次或者多次
X{n}?匹配X n次
X{n,}?匹配X至少n次
X{n,m}?匹配X至少n次,至多m次
  • 强匹配(更加贪婪)
    这个匹配和贪婪匹配的匹配规则一样,但是希望匹配次数尽可能多
字符匹配内容
X?+匹配X一次或者零次
X*+匹配X零次或者多次
X++匹配X一次或者多次
X{n}+匹配X n次
X{n,}+匹配X至少n次
X{n,m}+匹配X至少n次,至多m次
  • 逻辑运算
字符匹配内容
XYX之后是Y
XY
(X)X作为一个组
  • 反向引用
    反向引用允许在同一正则表达式中随后标识以前匹配的子表达式。
字符匹配内容
\n后向引用,匹配编号为n的子表达式的值
\k< name >命名后向引用,匹配命名表达式的值。
  • 引用
字符匹配内容
\无意义,引用其后字符
\Q无意义,引用其后所有字符,直到遇到\E
\E无意义,作为\Q引用的结尾
  • 特殊构造(命名组和非捕获组)
字符匹配内容
(?< name>X)给匹配X的字符串命名并捕获
(?:X)定义非捕获组
(?idmsuxU-idmsuxU)应用或禁用flags匹配选项i d m s u x U
(?=X)零宽度正预测先行断言。即匹配X的最相近的前面的字符
(?!X)零宽度负预测先行断言
(?<=X)零宽度正回顾后发断言
(?< !X)零宽度负回顾后发断言
(?>X)非回溯(也称为“贪婪”)子表达式

反斜杠、转义和引号

“\”反斜杠主要用来转义,上文很多地方都有用到,当匹配符号的时候,尤其有用。比如匹配左大括号写成“{”。但不应该把它用在字母前或者数字前。
在 Java 源代码中的字符串内的反斜杠会根据 Java™ 语言规范被解释为 Unicode 转义符或其他字符转义,故有必要在字符串中用双反斜杠表示正则表达式来保护他们免受Java 字节码编译器错误解释。字符串文字”\b”,例如,匹配单个退格键字符时解释为正则表达式,而”\b”匹配一个字边界。字符串”(hello)”是非法的会导致编译时错误;要匹配的字符串 (hello) 的字符串”\(hello\)”,必须使用。


字符类

字符类可能会包含其他字符类,也可能是并关系或者相交关系。并关系比如[a-dx-z],字符只要在[a-d]或者[x-z]的范围里即可。相交关系比如[a-z&&[x-z]],字符必须同时被包含在两个集中,这里只能匹配x,y或z。
字符类运算符先后顺序,由高到第依次是

顺序类别示例
1转义符\x
2[…]
3范围[a-z]
4[a-e][i-u]
5相交[a-z&&[aeiou]]

注意元字符,当它写成范围时和单独写意义是不一样的。


行结束符

行结束符是一行字符结尾的标记,有这么几种形式。

  • 新行行首(‘\n’)
  • 回车换行(“\r\n”)
  • 单纯回车(‘\r’)
  • 新行Unicode字符(‘\u0085’)
  • 行分隔符(‘\u2028’)
  • 段落分隔符(‘\u2029’)

如果设置了UNIX_LINES模式,那么只有‘\n’被认作是行结束符。
除非设置DOTALL模式,否则任何正则匹配都会忽略行结束符。
默认情况下,正则匹配符号^和 MULTILINE 会定位在上一行的结束符或者这段文本的最后一个行结束符。


分组和捕获

捕获组是从左到右按照括号先后进行计数的。在表达式((A)(B(C)))中,可以读到四个组。

组号组内容
1((A)(B(C)))
2(A)
3(B(C))
4(C)

0号组永远代表整个表达式。
捕获组之所以如此命名,是因为在匹配过程中,每一个被匹配成功的子字符串都会被保存。可能被匹配的子字符串还会在表达式的后面用到,如通过反向引用,在完成匹配操作后从被匹配的子字符中进行检索。


组命名

被捕获组也可以设置一个名字,那这个有名字的捕获组后续被引用时将依据其名字。组名由下列字符组成,但第一个字符必须是字母。

  1. 大写字母A-Z(‘\u0041’到‘\u005a’)
  2. 小写字母a-z(‘\u0061’到‘\u007a’)
  3. 数字0-9(‘\u0030’到‘\u0039’)

命名捕获组仍然会被组号进行编号标记。
这个命名捕获组一定是最近的那个被匹配成功的子字符串。如果这个组遇到了第二次可以匹配的情形,但第二次匹配并未成功,那么组仍旧保留第一次匹配的值。比如字符串“aba”匹配正则(a(b)?)+,它的组二设为b。每一轮匹配开始前所有捕获组都会清空。
如果组前加?或者什么也没加,那意味着这个组匹配的对象不会被捕获,也不会被计数。


Unicode支持

该类是符合级别 1 的 Unicode 技术标准 #18: Unicode 正则表达式,以及 RL2.1 规范的等价物。
Unicode转义字符如\u2014在Java源代码中依照Java™ 语言规范第 3.3 节所述,它可以直接用于正则表达式,因此同样能够从文件中或者键盘上读取到该值。字符串“\u2014”和“\u2014”尽管不同,但编译的时候都是一样的,都是匹配十六进制为0x2014的字符。
Unicode字符在正则表达式中也可以用它的十六进制值表示,即\x{…},比如补充字符U+2011F能够写成\x{2011F}的形式,而不是由两个Unicode转义字符组成的形式\uD840\uDD1F。
Unicode的脚本、块、类别和二进制属性与Perl里的规则相同,都使用\p和\P构造。\p{prop}匹配的是含有prop属性的文本,而\P{prop}匹配的是不含有prop属性的文本。
无论是内部字符类还是外部字符类,都可以使用脚本、块、类别和二进制属性。

脚本或者以Is为前缀,比如IsHiragana;或者使用script关键字(亦或它的简写形式sc),即script=Hiragana or sc=Hiragana。
由Pattern类支持的脚本名称是通过UnicodeScript.forName获取并定义的。

或者以In为前缀,如InMongolian;或者用block关键字(亦或它的简写blk),即block=Mongolian or blk=Mongolian。
由Pattern类支持的块名称是通过UnicodeBlock.forName获取并定义的。
类别可能会用到Is前缀(可选):\p{L}和\p{IsL}都表示Unicode字符类,和脚本、块相同,也能用关键字general_category(亦或它的简写gc),即general_category=Lu or gc=Lu。
可被支持的类在Unicode标准中由Character类定义。这些类别的名字可能是规范的,也可能不规范。

二进制属性都有Is前缀,比如IsAlphabetic,由Pattern支持的二进制属性有Alphabetic, Ideographic, Letter, Lowercase, Uppercase, Titlecase, Punctuation, Control, White_Space, Digit, Hex_Digit, Join_Control, Noncharacter_Code_Point, Assigned。
下面是预定义的字符类和POSIX字符类,都符合Annex C(我也不晓得是什么),当flag属性设置为UNICODE_CHARACTER_CLASS时兼容Unicode正则表达式。

ClassesMatches
\p{Lower}A lowercase character:\p{IsLowercase}
\p{Upper}An uppercase character:\p{IsUppercase}
\p{ASCII}All ASCII:[\x00-\x7F]
\p{Alpha}An alphabetic character:\p{IsAlphabetic}
\p{Digit}A decimal digit character:p{IsDigit}
\p{Alnum}An alphanumeric character:[\p{IsAlphabetic}\p{IsDigit}]
\p{Punct}A punctuation character:p{IsPunctuation}
\p{Graph}A visible character: [^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]
\p{Print}A printable character: [\p{Graph}\p{Blank}&&[^\p{Cntrl}]]
\p{Blank}A space or a tab: [\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]
\p{Cntrl}A control character: \p{gc=Cc}
\p{XDigit}A hexadecimal digit: [\p{gc=Nd}\p{IsHex_Digit}]
\p{Space}A whitespace character:\p{IsWhite_Space}
\dA digit: \p{IsDigit}
\DA non-digit: [^\d]
\sA whitespace character: \p{IsWhite_Space}
\SA non-whitespace character: [^\s]
\wA word character: [\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]
\WA non-word character: [^\w]

类别也可以应用像java.lang.Character的方法ismethodname,返回布尔值(弃用的类别除外)。这里也是通过\p{prop}标记来确定prop对于的属性名是否有同名javamethodname。


与Perl5比较

(略)


变量

声明类型变量名描述
static intCANON_EQ启用规范等价
static intCASE_INSENSITIVE启用不区分大小写的匹配
static intCOMMENTS允许模式中存在空白格和注释
static intDOTALL启用dotall模式(匹配所有字符,包括换行符)
static intLITERAL该模式下元字符和转义字符不再有特殊意义,全部按照原义字符处理
static intMUTILINE多行模式下^和$匹配的是整个文本的开头和结尾,中间换行符不匹配
static intUNICODE_CASE不区分大小写匹配,默认情况下只有US-ASCII有效果
static intUNICODE_CHARACTER_CLASS能够使用预定义的字符类和POSIX字符类
static intUNIX_LINES该模式下只有‘\n’行结束符符合.,^和$。

方法

声明类型方法名描述
Predicate< String>asPredicate()创建谓词用于匹配字符
static Patterncompile(String regex)将给定的正则表达式进行编译
static Patterncompile(String regex, int flags)将给定的正则表达式按照flags规则进行编译
intflags()返回这个pattern的flags值
Matchermatcher(CharSequence input)创建一个matcher对象用这个pattern匹配input
static booleanmatches(String regex, CharSequence input)创建一个matcher对象用给定正则表达式匹配input
Stringpattern()返回这个pattern类已编译的正则表达式
static Stringquote(String s)返回给定s的文本模式,即元字符和转义字符不具有特殊含义,全部被认为是原义字符
String[]split(CharSequence input)根据这个pattern的匹配结果将input分割
String[]split(CharSequence input, int limit)根据这个pattern的匹配结果将input分割,limit大于0的话被分割的字符串数量超出limit个时,那数组中最后一个字符串就把剩下的都囊括了,也就不继续分割了。如果小于0,数组为任意长度。如果等于0,数组为任意长度,被分割出的空字符串会被抛弃。
Stream< String>splitAsStream(CharSequence input)将给定input切成字符串流
StringtoString()返回这个pattern的字符串表示形式

参考网址:https://msdn.microsoft.com/zh-cn/library/az24scfc(v=vs.110).aspx

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值