java 的正则表达式

2021/02/05 Java初级进阶 共 2636 字,约 8 分钟
闷骚的程序员

1. 正则表达式简介

几乎任何计算机编程语言都支持正则表达式,比如一些脚本语言、linux命令等都支持。
正则表达式本质是个表达式,有自己的编写规则。
在java中正则表达式是嵌入到String类型中的,所以在java中正则表达式是一个特殊的匹配字符串【注意在java中其本质是字符串】。
但是在有的语言比如js中,正则表达式有可能是个单独的表达式,被定义在//中。

2. java和正则表达式的关系

java和正则表达式是相互独立的,正则表达式是独立的一套特殊表达式,它不仅仅适用于java语法,还适用于很多其他语言,只要java按照自己的特殊方式支持正则表达式,就可以将正则表达式的语法看做是java语法的一部分子属性。
正则表达式最初来源于神经学。

3. 正则表达式的作用

java中正则表达式本身就是一串特殊的字符串,这个特殊的字符串本身的作用就是用来对数据进行匹配。还可以执行更加复杂的 字符串验证、拆分、替换 功能。
总结,字符串规则匹配体现在下面三个方面:

  1. 字符串规则验证(即匹配)
  2. 字符串按照规则拆分
  3. 字符串按照规则替换
    注意在java中正则表达式只能嵌入到String字符串的定义中来指定。

4. java中使用正则表达式依赖的类

正则表达式的实现需要依赖Pattern和Matcher这两个类:
这两个类都在java.util.regex包中定义,Pattern类主要作用是指定正则规范(即指定正则表达式);
而Matcher类主要功能就是执行正则规范(即验证目标字符串是否符合其规范)。

5. 常用的正则规范定义(用来定义正则表达式)

表1 常用正则规范(区分正则表达式中的特殊字符的特殊含义,这些特殊含义需要转义

\\ :表示反斜线(\)字符
\t :表示制表符
\n :表示换行
[abc] :字符a、b或者c
[^abc] :表示除了a、b、c以外的任意字符
[a-zA-Z0-9] :表示由任意的一个字母、数字组成
\d :表示任意一个数字
\D :表示任意一个非数字
\w :表示任意的一个字母、数字、下划线
\W :表示任意一个非字母、非数字、非下划线
\s :表示所有空白字符(换行、空格等)
\S :表示所有非空白字符
^ :以。。开始,比如^[0-9]表示以任意一个数字开始;
$ :以。。结尾,比如$[a-z]表示以任意一个小写字母结尾;
. :匹配除了换行符\n以外的任意字符
| :在正则表达式中表示或者
\. :表示普通字符.
\| :表示普通字符|
\^ :表示普通字符^
\$ :表示普通字符$
\b :表示单词的边界

表2 数量表示(X表示一组规范表达式)

X :必须出现一次;等价于X{1}
X? :可以出现0次或者1次;等价于X{0,1}
X* :可以出现0次、1次或者多次;等价于X{0,}
X+ :可以出现1次或者多次;等价于X{1,}
X{n} :必须出现n次
X{n,} :必须出现n次以上
X{n,m} :必须出现n~m次

表3 逻辑运算符(X,Y表示一组规范表达式)

XY :X规范后跟着Y规范
X|Y :X规范或者Y规范
(X) :作为一个捕获组规范

表4 特殊的运算符

() :两层含义:一是改变正则表达式的优先级,二是分组
[] :两层含义:一是指定范围,比如[0-9][a-z]等,二是屏蔽正则表达式中元字符的特殊含义,比如[.]在正则表达式中就表示.的字面含义(发现使用[]来屏蔽特殊含义比使用\\.的方式来转义更方便)
? :两层含义:一是表示前面的正则表达式规范出现0次或者1次;二是阻止正则表达式的贪婪模式。
^ :两层含义:一是表示以…开始,当用在[]外边的时候表示以..开始,比如^[AZ]表示以任意一个大写字母开始;二是表示取非,当用在[]里面的时候表示取非,比如[^0-9]表示不是任意一个数字。
^$ :^$里面的规范,表示的是严格模式;而不使用^$,则表示的是非严格模式。java中的正则表达式默认就是严格模式的。

6. java中表示正则表达式的方式

从正则规范定义可以看到java中用于指定正则表达式的语法,前面也说过,java中并没有提供其他的方式来指定正则表达式,而是采用String的类型来指定正则表达式。
所以,在java中,可以将正则表达式看做一串特殊规则的字符串!
但是,本质上,正则表达式的规则只是针对正则表达式本身的,而不是针对普通字符串的,这句话的含义可以这样理解:

  1. 案例1
    如果单纯的指定正则表达式,则\d在正则表达式中表示匹配任意一个数字,即\d。但是在java中只能使用String来表示\d,即String regex = “\d”;这样一来,\d在正则表达式中是正确的,但是在String字符串中这个是错误的!
    原因分析:
    java通过String来指定正则表达式,所以java将正则表达式和String字符串耦合了。既然这样,String regex = “\d”;表示定义一个字符串,既然是字符串,就要考虑转义字符了,我们知道java中对于字符串而言,\d就表示将字符d进行转义,而不表示字面含义\d,而java不支持\后面跟个字符d,所以字符串中出现\d就导致语法错误,那么想要在String中表示出字面含义\d(注意,\d在String中是字面含义,但其实\d是通过String形式来定义的正则表达式,即尽管现在String对象中存放的就是\d,但是转换为正则表达式后\d就表示匹配任意一个数字了),就需要对\的特殊含义进行转义,我们知道\才表示\,
    所以下面的方式才是正确的正则表达式在java中的指定:
    String regex = “\d”;//regex对象中存放的是\d,而\d字符转换成正则表达式后表示匹配任意一个字符
    结论:从这点可以看出,其实正则表达式不是字符串,正则表达式和java中的字符串是相互独立的,只是因为java中使用String类型来指定正则表达式,所以,在java中才可以将正则表达式看做一个特殊规则的字符串。
  2. 案例2
    我们知道,正则表达式中.表示特殊含义;而想表示.的普通含义,正则表达式可以使用.来表示。
    基于上面的分析,可以知道,.在正则表达式中表示普通字符.。那么我们现在通过String来定义正则表达式:
    String regex = “.”;//同样这句话是错误的,因为\在普通字符串中表示特殊含义,.在普通字符串中并不表示.的字面含义,所以java不支持,所以报错。
    String regex = “\.”;//这是正确的,因为\在字符串中转义了表示\,所以\.在字符串中表示.,即regex对象中存储的是.的字面含义,再转换成正则表达式就表示.的字面含义了。

文档信息

Search

    Table of Contents