Java正则表达式详解
正则表达式(Regular Expression)又称正规表示法、常规表示法,在代码中常简写为 regex、regexp 或 RE,它是计算机科学的一个概念。
正则表达式是一个强大的字符串处理工具,可以对字符串进行查、提取、分割、替换等操作,是一种可以用于模式匹配和替换的规范。一个正则表达式就是由普通的字符(如字符 a~z)以及特殊字符(元字符)组成的文字模式,它用以描述在查文字主体时待匹配的一个或多个字符串。
String 类里也提供了如下几个特殊的方法。
∙boolean matches(String regex):判断该字符串是否匹配指定的正则表达式。
∙String replaceAll(String regex, String replacement):将该字符串中所有匹配 regex 的子串替换成 replacement。
∙String replaceFirst(String regex, String replacement):将该字符串中第一个匹配 regex 的子串替换成 replacement。
∙String[] split(String regex):以 regex 作为分隔符,把该字符串分割成多个子串。
上面这些特殊的方法都依赖于 Java 提供的正则表达式支持,除此之外,Java 还提供了 Pattern 和 Matcher 两个类专门用于提供正则表达式支持。
很多读者都会觉得正则表达式是一个非常神奇、高级的知识,其实正则表达式是一种非常简单而且非常实用的工具。正则表达式是一个用于匹配字符串的模板。实际上,任意字符串都可以当成正则表达式使用。例如“abc”,它也是一个正则表达式,只是它只能匹配“abc”字符串。
如果正则表达式仅能匹配“abc”这样的字符串,那么正则表达式也就不值得学习了。正则表达式作为一个用于匹配字符串的模板,将某个字符模式与所搜索的字符串进行匹配。本文简单了解一下如何使用正则表达式来操作字符串。
正则表达式支持字符
创建正则表达式就是创建一个特殊的字符串。正则表达式所支持的合法字符如表 1 所示。
表 1 正则表达式所支持的合法字符 | |
字符 | 解释 |
X | 字符x(x 可代表任何合法的字符) |
\0mnn | 八进制数 0mnn 所表示的字符 |
\xhh | 十六进制值 0xhh 所表示的字符 |
\uhhhh | 十六进制值 0xhhhh 所表示的 Unicode 字符 |
\t | 制表符(“\u0009”) |
\n | 新行(换行)符(‘\u000A’) |
\r | 回车符(‘\u000D’) |
\f | 换页符(‘\u000C’) |
\a | 报警(bell)符(‘\u0007’) |
\e | Escape 符(‘\u001B’) |
\cx | x 对应的的控制符。例如,\cM匹配 Ctrl-M。x 值必须为 A~Z 或 a~z 之一。 |
除此之外,正则表达式中有一些特殊字符,这些特殊字符在正则表达式中有其特殊的用途,比如前面介绍的反斜线\。
如果需要匹配这些特殊字符,就必须首先将这些字符转义,也就是在前面添加一个反斜线\。正则表达式中的特殊字符如表 2 所示。
表 2 正则表达式中的特殊字符 | |
特殊字符 | 说明 |
$ | 匹配一行的结尾。要匹配 $ 字符本身,请使用\$ |
^ | 匹配一行的开头。要匹配 ^ 字符本身,请使用\^ |
() | 标记子表达式的开始和结束位置。要匹配这些字符,请使用\(和\) |
[] | 用于确定中括号表达式的开始和结束位置。要匹配这些字符,请使用\[和\] |
{} | 用于标记前面子表达式的出现频度。要匹配这些字符,请使用\{和\} |
* | 指定前面子表达式可以出现零次或多次。要匹配 * 字符本身,请使用\* |
+ | 指定前面子表达式可以出现一次或多次。要匹配 + 字符本身,请使用\+ |
? | 指定前面子表达式可以出现零次或一次。要匹配 ?字符本身,请使用\? |
. | 匹配除换行符\n之外的任何单字符。要匹配.字符本身,请使用\. |
\ | 用于转义下一个字符,或指定八进制、十六进制字符。如果需匹配\字符,请用\\ |
| | 指定两项之间任选一项。如果要匹配丨字符本身,请使用\| |
将上面多个字符拼起来,就可以创建一个正则表达式。例如:
"\u0041\\\\" // 匹配 A\
"\u0061\t" // 匹配a<制表符>
"\\?\\[" // 匹配?[
注意:可能大家会觉得第一个正则表达式中怎么有那么多反斜杠?这是由于 Java 字符串中反斜杠本身需要转义,因此两个反斜杠(\\)实际上相当于一个(前一个用于转义)。
上面的正则表达式依然只能匹配单个字符,这是因为还未在正则表达式中使用“通配符”,“通配符”是可以匹配多个字符的特殊字符。正则表达式中的“通配符”远远超出了普通通配符的功能,它被称为预定义字符,正则表达式支持如表 3 所示的预定义字符。
表 3 预定义字符 | |
预定义字符 | 说明 |
. | 可以匹配任何字符 |
\d | 匹配 0~9 的所有数字 |
\D | 匹配非数字 |
\s | 匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等 |
\S | 匹配所有的非空白字符 |
\w | 匹配所有的单词字符,包括 0~9 所有数字、26 个英文字母和下画线_ |
\W | 匹配所有的非单词字符 |
上面的 7 个预定义字符其实很容易记忆,其中:
∙d 是 digit 的意思,代表数字。
∙s 是 space 的意思,代表空白。
∙w 是 word 的意思,代表单词。
∙d、s、w 的大写形式恰好匹配与之相反的字符。
有了上面的预定义字符后,接下来就可以创建更强大的正则表达式了。例如:
c\\wt // 可以匹配cat、cbt、cct、cOt、c9t等一批字符串
\\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d // 匹配如 000-000-0000 形式的电话号码
在一些特殊情况下,例如,若只想匹配 a~f 的字母,或者匹配除 ab 之外的所有小写字母,或者匹配中文字符,上面这些预定义字符就无能为力了,此时就需要使用方括号表达式,方括号表达式有如表 4 所示的几种形式。
表 4 方括号表达式 | |
方括号表达式 | 说明 |
表示枚举 | 例如[abc]表示 a、b、c 其中任意一个字符;[gz]表示 g、z 其中任意一个字符 |
表示范围:- | 例如[a-f]表示 a~f 范围内的任意字符;[\\u0041-\\u0056]表示十六进制字符 \u0041 到 \u0056 范围的字符。范围可以和枚举结合使用,如[a-cx-z],表示 a~c、x~z 范围内的任意字符 |
表示求否:^ | 例如[^abc]表示非 a、b、c 的任意字符;[^a-f]表示不是 a~f 范围内的任意字符 |
表示“与”运算:&& | 例如 [a-z&&[def]]是 a~z 和 [def] 的交集,表示 d、e f[a-z&&^bc]]是 a~z 范围内的所有字符,除 b 和 c 之外 [ad-z] [a-z&&[m-p]]是 a~z 范围内的所有字符,除 m~p 范围之外的字符 |
表示“并”运算 | 并运算与前面的枚举类似。例如[a-d[m-p]]表示 [a-dm-p] |
时间正则表达式java方括号表达式比前面的预定义字符灵活多了,几乎可以匹配任何字符。例如,若需要匹配所有的中文字符,就可以利用 [\\u0041-\\u0056] 形式——因为所有中文字符的 Unicode 值是连续的,只要出所有中文字符中最小、最大的 Unicode 值,就可以利用上面形式来匹配所有的中文字符。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论