Java正则表达式

小编
小编
小编
172
文章
1
评论
2020-09-2714:06:42 评论 1,929

正则表达式(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 所示。

Java正则表达式

除此之外,正则表达式中有一些特殊字符,这些特殊字符在正则表达式中有其特殊的用途,比如前面介绍的反斜线\。

如果需要匹配这些特殊字符,就必须首先将这些字符转义,也就是在前面添加一个反斜线\。正则表达式中的特殊字符如表 2 所示。

Java正则表达式

将上面多个字符拼起来,就可以创建一个正则表达式。例如:

"\u0041\\\\" // 匹配 A\

"\u0061\t"  // 匹配a<制表符>

"\\?\\["    // 匹配?[

注意:可能大家会觉得第一个正则表达式中怎么有那么多反斜杠?这是由于 Java 字符串中反斜杠本身需要转义,因此两个反斜杠(\\)实际上相当于一个(前一个用于转义)。

上面的正则表达式依然只能匹配单个字符,这是因为还未在正则表达式中使用“通配符”,“通配符”是可以匹配多个字符的特殊字符。正则表达式中的“通配符”远远超出了普通通配符的功能,它被称为预定义字符,正则表达式支持如表 3 所示的预定义字符。

Java正则表达式

上面的 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(点击表格查看大图) 所示的几种形式。

Java正则表达式

方括号表达式比前面的预定义字符灵活多了,几乎可以匹配任何字符。例如,若需要匹配所有的中文字符,就可以利用 [\\u0041-\\u0056] 形式——因为所有中文字符的 Unicode 值是连续的,只要找出所有中文字符中最小、最大的 Unicode 值,就可以利用上面形式来匹配所有的中文字符。

正则表达式还支持圆括号,用于将多个表达式组成一个子表达式,圆括号中可以使用或运算符|。例如,正则表达式“((public)|(protected)|(private))”用于匹配 Java 的三个访问控制符其中之一。

除此之外,Java 正则表达式还支持如表 5 所示的几个边界匹配符。

Java正则表达式

前面例子中需要建立一个匹配 000-000-0000 形式的电话号码时,使用了 \\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d 正则表达式,这看起来比较烦琐。实际上,正则表达式还提供了数量标识符,正则表达式支持的数量标识符有如下几种模式。

Greedy(贪婪模式):数量表示符默认采用贪婪模式,除非另有表示。贪婪模式的表达式会一直匹配下去,直到无法匹配为止。如果你发现表达式匹配的结果与预期的不符,很有可能是因为你以为表达式只会匹配前面几个字符,而实际上它是贪婪模式,所以会一直匹配下去。

Reluctant(勉强模式):用问号后缀(?)表示,它只会匹配最少的字符。也称为最小匹配模式。

Possessive(占有模式):用加号后缀(+)表示,目前只有 Java 支持占有模式,通常比较少用。

三种模式的数量表示符如表 6 所示。

Java正则表达式

关于贪婪模式和勉强模式的对比,看如下代码:

String str = "hello,java!";
// 贪婪模式的正则表达式
System.out.println(str.replaceFirst("\\w*" , "■"));    //输出■,java!
// 勉强模式的正则表达式
System.out.println(str.replaceFirst("\\w*?" , "■""));    //输出■hello, java!

当从“hello java!”字符串中查找匹配\\w*子串时,因为\w*使用了贪婪模式,数量表示符*会一直匹配下去,所以该字符串前面的所有单词字符都被它匹配到,直到遇到空格,所以替换后的效果是“■,Java!”;如果使用勉强模式,数量表示符*会尽量匹配最少字符,即匹配 0 个字符,所以替换后的结果是“■hello,java!”。

匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: