【Java】java.util.Pattern详述

来源:互联网 发布:java飞机大战子弹 编辑:程序博客网 时间:2024/05/15 23:47

java.util.Pattern详述

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

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

类声明

public final class Patternextends Objectimplements 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’) \cx x指定的 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次
  • 逻辑运算
字符 匹配内容 XY X之后是Y X Y (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正则表达式。

Classes Matches \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} \d A digit: \p{IsDigit} \D A non-digit: [^\d] \s A whitespace character: \p{IsWhite_Space} \S A non-whitespace character: [^\s] \w A word character: [\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}] \W A non-word character: [^\w]

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


与Perl5比较

(略)


变量

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

方法

声明类型 方法名 描述 Predicate< String> asPredicate() 创建谓词用于匹配字符 static Pattern compile(String regex) 将给定的正则表达式进行编译 static Pattern compile(String regex, int flags) 将给定的正则表达式按照flags规则进行编译 int flags() 返回这个pattern的flags值 Matcher matcher(CharSequence input) 创建一个matcher对象用这个pattern匹配input static boolean matches(String regex, CharSequence input) 创建一个matcher对象用给定正则表达式匹配input String pattern() 返回这个pattern类已编译的正则表达式 static String quote(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切成字符串流 String toString() 返回这个pattern的字符串表示形式

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

0 0
原创粉丝点击