本文主要是介绍万事万物皆正则 -- Java正则表达,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一:吹逼前言
正则表达式是很多Javer自动忽略的知识点,不可否认具备一定的难度,并且在线正则生成的开源也催化了这种现象的普遍性。前段时间偶然听说一则新闻某知名IT大神吐槽不会正则的程序员不配称呼程序员,正则表达式的运用场景属实在编程中广泛存在。不求精通,但求略懂。至少需要达到当遇到一个不是很复杂正则我们可以进行解析,编辑正则还是在线生成吧。开源还是存在一定逻辑,手撸正则谁知道是什么情况
二:Java支持
Java在JDK1.4增加了对正则表达式的支持,也就是java.util.regex包,下面常用的两个类为Patter与Matcher。Patter负责解析正则表达式,Matcher负责将字符与表达式进行匹配。其中Patter未提供public的构造函数,依赖方法compile()返回对象实例,Matcher对象实例依靠Patter类matcher()返回,简易操作示例如下:
需要注意一点就是目前Java中字符串的匹配还是交给String类的matches()方法完成,不必进行如此复杂的操作。查看String类的该方法源码如下,发现还是调用Patter类的静态方法matches()
三:基础规则
因为本文是根据Java基础进行讲解,需要注意特别的一点。总所周知".
“在正则中匹配所有单字符出\n外,如果想让其表示一般文本语义,则需要使用转义符号”\
"。注意这个转义符号在Java中也需要使用"\
“进行转义,也就是最后的呈现方式为”\\.
"
3.1 限定符
限定符也就是限制给定组件可以出现的次数,注意限定符必须出现在普通字符或非打印字符之后,也就是不能单独出现,且限定符只能限制前一个字符的范围
符号 | 含义 |
---|---|
? | 0或者1个字符 |
* | 0或者多个字符 |
+ | 1或者无数个字符 |
{m,n} | 最少m个,最多n个,n为空代表无数多 |
解释一下什么叫限制前一个字符,如下示例。限定符{3,4}只是限制字符b出现的次数,而不能限制a,那么a还是只能出现这一次。所以最后结果为false
3.2 一组字符
想要让某个位置出现很多种情况,例如可能是1、2、5、a、A怎么办?如上所示,这时候使用中括号“[]
“”表示一组字符
3.3 数字元字符
如果想要表达一个字符是数字,可以采取的方式有如下几种,注意其中的"-
“不在”[]
"中只能表示普通字符,不能表示范围:
- [0-9]:表示数字0-9都可以匹配
- \d:等同于[0-9]
- \D:表示非数字,与前两者相反
3.4 字母元字符
如果想要表达一个字符为字母,那么就有如下几种方式,与数字元字符规则类似:
- [a-z]:表示a-z的小写字母
- [A-Z]:表示A-Z的大小字母
- [a-zA-Z]:表示大写字母与小写字母
3.5 字母或数字或 _
表示数字可以使用\d进行简写表示,那么如果表示大小写字母、数字、下划线_可不可以有简写呢?肯定有的,如下所示:
- \w:等同于[a-z0-9A-Z]
- \W:与上述\w取反
3.6 取反、或
或操作就是要么是你要么是我,同或运算语义一致,使用符号"|
“表示
取反顾名思义就是杠精,使用尖括号”^
“表达内心不要的纯粹想法,注意这个取非的语义是在中括号”[]
"中使用才具备,其它地方使用表示语义下面讲解。同时注意这个取反是针对中括号内部全部取反
3.7 组划分
整个正则表达式可能是多个子级表达式组成,比如最开始讲到的匹配年-月-日就是由多个子表达式构成最后的正则表达式。如果需要标记某个子表达式开始与结束使用小括号"()
",最经典的使用莫过于子表达式后面跟限定符,表示对整个子表达式进行限定,而非对限定符前一个字符进行限定
3.8 定位符
将正则表达式固定到行首或者是行尾,当然定位符也包括很特殊但是十分重要的单词边界定位
符号 | 含义 |
---|---|
^ | 匹配输入字符串开始的位置,千万不要与中括号里面的^用法混淆 |
$ | 匹配输入字符串结束的位置 |
\b | 匹配单词边界,即字与空格之间的位置 |
\B | 匹配非单词边界 |
四:反向引用
说直白点就是查缓存,使用"()
“的子表达式匹配结果会放到缓存区。当需要复用该结果就可以使用\n复用,其中每个缓存会根据顺序按照下标1开始进行存储,\n中的n指定的就是缓存的下标
如果需要消除掉这个缓存的影响则可以使用”?:
"达到目标
五:前瞻与后顾
说直白一点就是看看前面的子表达式匹配的是不是预期或者看看后面的子表达式是否符合预期,有以下几种表现形式:
- (?=X):出现位置之后的字符串能匹配X
- (?<=X):出现位置之前紧跟着的字符串能匹配X
- (?!X):出现位置之后的字符串不能匹配X
- (?!<X):出现位置之前的字符串不能匹配X
六:贪婪与懒惰
两种正则的解析模式就是字面含义,贪婪尽可能多点、懒惰则尽可能少点。如上图所示,正则匹配后想看看有多少符合条件的子表达式,就是采用Matcher类的find()与group()方法。其实根据最后的结果来讲,理解这两种正则解析模式就是限定符位置会匹配多少字符串内容。针对这两种解析模式做出如下总结:
- 懒惰模式会在满足正则匹配后不影响后面子字符串的解析匹配,书写规则为在限定符后加?
- 贪婪模式会最大程度的根据正则表达式进行解析匹配,限定符默认为贪婪模式
- 这两种模式下有个共同点都会保证整体文本符合正则表达式解析情况下再发挥特点,这与下面讲解的独占模式有着本质区别
七:独占
独占是一个比较特殊的存在,不会对匹配解析进行回溯。结合上图你会理解这个回溯是什么意思,即限定符后跟+表示开启独占模式,这时的限定符就会最大程度匹配字符串与贪婪模式一致。但是贪婪模式再贪财也会注意整体大局,也就是示例中匹配到第三个c的时候它发现后面还需要c,如果这个c它匹配了以后整体文本将不会符合正则表达式,这时贪婪模式下会选择放弃匹配回溯,让后面的c进行匹配解析。独占模式可就不管这些,只要符合的都要,最后整个字符串文本是否符合规则与我无关
这篇关于万事万物皆正则 -- Java正则表达的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!