正则表达式简明

正则表达式简明

Mar 04, 2022 ·
9 分钟阅读

前言

对于正则表达式,我们使用它的场景大致分类来讲有两种:

对于场景,具体到使用的Java API:

  1. 对字符串进行固定规则的校验,输出是否满足该正则表达式表示的规则,即匹配字符matcher.matches()
  2. 对字符串按照固定规则提取子串,可以按照组输出指定的子串,即匹配字符+分组matcher.group()
  3. 对字符串按照位置进行替换/插入,即匹配位置matcher.replaceAll()

一 匹配字符

模糊匹配

正则表达式可以是一个没有任何规则的字符串,如:hello,那它就只能匹配“hello”这一个字符串。模糊匹配可以针对待匹配字符串的可变子串做横向和纵向两种模糊匹配:

字符组

[abc] 字符组就是表示在当前位置可能出现的字符的集合。注意⚠️,虽然叫组,但是只表示匹配一个字符,不管这个组再长,一对中括号也只能匹配一个字符。

量词

{m,n}

多选分支

多选分支属于字符组的一种,可以给待匹配的字符串分支选择。简单来说,类似于“枚举”,要么匹配a,要么匹配b。表示为a|b。 例:表达式:good|goodbye 待匹配字符串:goodbye & good &goodbye!

我们给表达式添加分组,可以发现多选分支是惰性的。

二 匹配位置

基本规则下,我们只需要知道^代表匹配开头,$代表匹配结尾。 一般情况下,我们在整个表达式的开始写上^,结束写上$,代表我要匹配的字符串必须以啥开头,并且以啥结束。 例:表达式:a\d+b & ^a\d+b$ 待匹配字符串:a123b & a123bab 在Java中,findmatch的区别基本可以认为match是自带了^$,所以可以认为这两个字符只影响find方法。但是不同的正则表达式解析器方法不同,为了你这段表达式的健壮性,一般推荐都加上。

三 分组

在一开始横向模糊匹配的部分,我们说量词是“表示这个花括号前面的子串连续出现的次数”,那这个子串有多长呢?实际上就是一个字符的长度。如果我想对一组字符重复多次呢——比如“goodgoodgood”这种情况? 例:表达式:good{3} & (good){3} 待匹配字符串:goodgoodgood 分组,表示为(),可以把一些字符划成一堆,基本可以理解为数学表达式里的括号,括号右边的东西可以把括号里所有的东西当成一个整体。

分组和分支结合

(p1|p2)分组可以让分支的表示更清晰,因此在用到分支的时候大多数都会也用到分组。 例:表达式:^Java is good|bad$ & ^Java is (good|bad)$ 待匹配字符串:Java is bad & Java is bad

引用分组

这里把它称作提取子串更容易理解。对于匹配上的字符串来讲,被分组匹配上的字符串是可以提取出来的。

Java中Matcher.group()可以提取匹配上分组的字符串,Matcher.groupCount()返回匹配上分组的数量。 Matcher.group(0)固定代表待匹配字符串本身,不计入Matcher.groupCount()中。 例:表达式:\d{4}-\d{2}-\d{2} & \d{4}-\d{2}-\d{2} 待匹配字符串:2022-03-01