1 介绍

我知道各位小伙伴刚学习正则时候一定十分抓狂,因为我就是,而且这东西并没有太大的逻辑,语法一大堆,所以一段时间忘记了,重新拾起还超级难,我真服了,可以说毫无头绪。

所以为了让小伙伴们无论是从初学还是复习更好的学习,我准备一步步从超级简单的语法开始,一步步往深里学,一步步了解如何使用正则表达式。

这里的示例都是用Java实现,但是正则表达式的匹配规则是通用的,所以其它语言的小伙伴也可以从这里入门学习匹配规则。

PS:推荐加个匹配网站,里面还有对正则表达式的讲解。只不过是因为英文的,可以尝试用翻译。

https://regexr.com/​regexr.com/

2 作用

Java中,正则表达式有好几种用法,常用于以下情况:(下面的代码不用看懂,只要知道它在干啥就行)

  • 验证输入的数据是否符合某个规则,例如邮箱、电话号码、身份证号等是否符合规范。

String text = "13912345678"; // 字符串
String regex = "1[3456789]\\d{9}"; // 正则表达式匹配规则
boolean match = text.matches(regex); // 判断字符串是否符合规范
// 如果上面的text符合regex规范,则返回true
  • 查找匹配特定模式的字符串,例如在一个字符串中查找所有邮件地址

// 正则表达式匹配电子邮件地址
String text = "Hello, mmy email address is john@example.com. "; // 字符串
String emailRegex = "\\w+@\\w+\\.\\w+"; // 正则表达式匹配规则
Pattern emailPattern = Pattern.compile(emailRegex);
Matcher emailMatcher = emailPattern.matcher(text);
// 打印所有匹配的电子邮件地址
while (emailMatcher.find()) {System.out.println("Email address: " + emailMatcher.group());
}
  • 替换字符串中符合特定模式的部分为指定的内容,例如将字符串中所有的手机号替换为“NEW”。

String text = "Hello, my phone number is 1234567890"; // 字符串
// 正则表达式替换手机号码为 "NEW"
String phoneRegex = "\\d{10}"; // 正则表达式匹配规则
Pattern phonePattern = Pattern.compile(phoneRegex);
Matcher phoneMatcher = phonePattern.matcher(text);
String redactedText = phoneMatcher.replaceAll("NEW"); // 替换成NEW

上面的例子就是让我们知道,java中正则可以做什么,不用担心看不懂,后面我们会一步步来学习。

综上所述,其实正则表达式就一个作用 —— 匹配。

验证、查找和替换都只是在匹配成功的处理而已,比如判断输入的手机号码是否符合规范,就是用对应的正则表达式去匹配,匹配成功,就说明验证成功;再比如替换,也是先对字符串中的内容进行正则匹配,找到所有符合规范的片段,再替换。

所以说,其实正则表达式就只提供了匹配这一个功能,其它验证、查找和替换的功能是Java自己扩展来的,所以我们只要学习正则表达式的匹配规则,就掌握了Java正则表达式的根本。掌握了这个根本,你也就掌握了其它语言中正则表达式的使用。

OK,话不多说,让我们开始一步步学习正则表达式的匹配规则吧!

3 最简单的匹配 —— 没有语法的匹配

OK,我们先不说其它语法,我们就从最简单的匹配开始 —— 啥语法也不用。

现在有一个字符串 —— "E先生斗图强的一匹!",我们现在匹配字符串字符串中"强的一匹",这几个字我们该怎么写?

很简单,就直接写"强的一匹"就行了,这样系统就会去匹配字符串中符合要求的片段。

示例代码如下:

示例一:
正则表达式:强的一匹
片段为:E先生斗图强的一匹!
结果为:强的一匹

是不是超级简单,直接无敌!

那你可能就问,那其他那些乱七八糟的语法都有啥用啊?而且日常匹配也没这么简单啊。

OK,那你就开始上道了,老baby,让我们开始更高难度的匹配吧!

4 无敌万能字符 —— "."

OK,现在假设我们要匹配的语句,我们只知道我们想要的一段话,是以"E"开头,"生"结尾,中间内容不知道,并且知道中间只有一个字,然后想要匹配这三个字匹配下来,那我们该怎么匹配?

比如内容是“E先生真的好帅啊!”

然后我们开始匹配以"E"开头,"生"结尾的内容。

示例如下:

示例一:
正则表达式:E.生
片段为:E先生斗图强的一匹!
结果为:E先生

通过上述的正则表达式“E.生”,我们就可以匹配到我们想要的内容。

是不是很简单,我们现在讲解一下这个特殊符号“.”

有什么作用呢?

简单来说,当我们无法确定具体头尾之间包含的字符是哪一个字的时候,可以用“.”来代替中间未知的字符。

如果中间缺两个字,我们可以写“E..真”,就可以匹配到“E先生真”。

是不是就像一个万能符号,哪里不明补哪里。

那我们了解了“.”的作用,但是如果我们又有一个需求呢?如果我们根本不知道开头和结束中间的内容有多少怎么办?

就好比,我们现在要匹配以“E”开头,"厉害"结尾的片段,但是我们完全不知道中间有多少个未知符号,如果只用“.”是根本无法完全匹配到我们想要的片段,如下例子:

字符串是"E先生超厉害!",我们可以用"E...厉害"来匹配,

但是如果字符串改为"E先生真的超厉害!",那"E...厉害"就没法用了,因为中间是四个未确定的字,所以根本就没有通用性。

那为了让正则表达式有通用性,那我们该怎么办呢?

OK,别着急,我们将引进更厉害的东西!follow me !

5 贪婪匹配 —— *

现在我们还是举上面的例子,

示例一:
正则表达式:E.*贼酷 // 表示匹配以E开头贼酷结尾,中间有一个未知字符的片段。
片段为:我的天啊!E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。
结果为:E先生,真是屁本事没有,斗图倒是有一手,贼酷

看到没有,我们只是加了一个字符"*",就解决了我们上面无法确定中间字符数量不确定的问题,成功匹配出我们想要的字符,是不是贼6!

OK,那我来讲解一下"*",它的作用就如上面示例所表现得,可以控制前面字符的匹配数量,匹配0个或者无数个,能够无限往后匹配,知道获取到最长并且符合要求的那段字符串,这也就是为什么叫它贪婪的原因。

我们再根据上面的例子重新描述一下,

示例一:
正则表达式:E.贼酷 // 表示匹配以E开头贼酷结尾,中间有一个未知字符的片段。
片段为:我的天啊!E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。
结果为:匹配失败正则表达式:E.*贼酷 // 表示匹配以E开头贼酷结尾,中间有无数个未知字符的片段。
片段为:我的天啊!E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。
结果为:E先生,真是屁本事没有,斗图倒是有一手,贼酷示例二:
正则表达式:E先*你好 // 表示匹配以E开头,你好结尾,中间有0或多个"先"字符的片段
片段为:hellow,E先先先你好!
结果为:E先先先你好

上面就“*”符号的作用,类似她的符号还有好几个常用的,如下,

符号

作用

示例

+

匹配前面的字符至少一次或多次。

"a+b" 可以匹配 "ab"、"aab"、"aaaaab" 等字符串,但不能匹配 "b"。

*

匹配前面的字符零次或多次。

"a*"可以匹配"ab"或者"b",之所以可以匹配b,因为就算没有匹配到也算,匹配成功。

各位小伙伴们,可以自己去探索一下,具体使用。

OK,又掌握了一个重要工具,又距离成功迈向一大步,让我们继续探索之路吧!

6 非贪婪匹配 —— "?"

我们可以看到上面的"*"和表格里面的"+"都是可以匹配后面的多个字符,那如果我们只想尽可能少的匹配,或者说只想匹配到符合要求的第一个呢?

这个时候我们就可以用问号来限制匹配数量。

我们举个例子说明一下,我们现在只想匹配所有书括号里面的信息。

示例一:
正则表达式:《.*》
片段为:《杀死一只知更鸟》,《传习录》,《西游记》这几本书都挺好看的。
匹配结果:《杀死一只知更鸟》,《传习录》,《西游记》示例二:
正则表达式:《.*?》
片段为:《杀死一只知更鸟》,《传习录》,《西游记》这几本书都挺好看的。
匹配结果:《杀死一只知更鸟》示例三:
正则表达式:《.*?》
片段为:《杀死一只知更鸟》,《传习录》,《西游记》这几本书都挺好看的。
全局匹配结果:结果0:《杀死一只知更鸟》结果1:《传习录》结果2:《西游记》

我们可以看到,示例一中没有加"?",所以会默认开启贪婪模式,比如当遇到"《杀死一只知更鸟》"这个到时候,其实就已经符合正则表达式的要求了,但是系统会继续往后尝试,会获取符合要求,最长的字符串,这个时候就会一直匹配到最后一个书括号,也就是有了"《杀死一只知更鸟》,《传习录》,《西游记》"这样一个最长并且符合要求的字符串了。

但是如果加了"?",我们可以看到他会跟贪婪模式相反,也就是会去获取符合要求的,并且最短的字符串,所以获取到"《杀死一只知更鸟》"就结束了。

如果开启全局匹配,也就是匹配多次,那就可以把所有的书名都作为单独的结果匹配下来。

这就是非贪婪模式的作用和实例。

但是你有没有发现上面的一个弊端,就是要么全都要,要么只要最短,难道我就不能控制匹配的数量?

7 量词符——"{}"

如果我们像控制匹配数量的话,我们可以通过量词符大括号来实现,它的语法如下,

{n}     指定需要匹配的次数
{n,}    指定至少需要匹配的次数
{n,m}   指定需要匹配的最少和最多次数。

我们看一下示例,

示例一:
正则表达式:9{2}
片段为:19997年的天空,真美啊!
匹配结果:99

可以看到,通过"{2}"来限制匹配9的数量为2,所以结果为2。

我们再看看后面的用法,

示例一:
正则表达式:9{2,}
片段为:9年前,19997年的天空,真美啊!
匹配结果:999

可以看到,通过"{2,}"来限制匹配9的至少是两个以上,所以当遇到"9年前"的9的时候,并不会匹配,因为不符合至少两个的要求,所以会跳过,匹配"19997"中的999。

我们再看最后一个示例,

示例一:
正则表达式:9{1,2}
片段为:9年前,19997年的天空,真美啊!
匹配结果:9

可以看到,通过"{1,2}"来限制匹配9的数量为1到2个,所以当遇到"9年前"的9的时候,也会匹配。

这个常用于全局匹配,也就是把字符串中符合要求的全部匹配出来,如下。

示例一:
正则表达式:9{1,2}
片段为:9年前,19997年的天空,真美啊!
全局匹配结果:结果0:9结果1:99结果2:9

我们可以发现,它会先把最长符合要求的匹配出来,再匹配次要符合要求的,比如999,它是先匹配到99,再匹配9。

8 定位符

OK,前面学的东西有点多,那我们学个小菜来缓解一下,我们学一下简单的两个符号——定位符,分别是"^","$"。

符合

作用

^

匹配字符串的开头

$

匹配字符串的结尾

我们再举两个例子说明一下,

示例一:
正则表达式:^E先生 // 表示匹配以"E先生"开头的片段。
片段为:E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。
结果为:E先生示例二:
正则表达式:^E先生 // 表示匹配以"E先生"开头的片段。
片段为:我的天啊!E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。
结果为:匹配失败
原因:因为片段不是以E先生开头的,所以无法匹配成功。示例三:
正则表达式:想学。$ // 表示匹配以"想学。"结尾的片段。
片段为:E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。
结果为:想学。示例四:
正则表达式:想学。$ // 表示匹配以"想学。"结尾的片段。
片段为:我的天啊!E先生,真是屁本事没有,斗图倒是有一手,贼酷,想学。。
结果为:匹配失败
原因:因为片段不是以“想学。”结尾的,所以无法匹配成功。

OK,上面就是简单的定位符的示例,是不是理解起来不难。

那中途休息后,我们继续学习后续的内容。

9 多才多艺的字符 —— "\"

9.1 转义

我们上面学习了这么多符号,那好巧不巧,这些符号正好是我们想要的匹配的,那咋整?

比如,我们要匹配"守护最好的****"这一整个完整片段,“*”是我们要匹配的字符,而不是通配符,那我们该怎么处理?

这时候就用到我们的转义符 ——“\”。

示例一:
正则表达式:守护最好的****
片段为:守护最好的****
结果为:匹配失败,*被识别为匹配符示例二:
正则表达式:守护最好的\*\*\*\*
片段为:守护最好的****
结果为:守护最好的****示例二:
正则表达式:192\.168\.13\.25
片段为:192.168.13.25
结果为:192.168.13.25

以上就是把正则表达式元字符转化为普通字符的方法。

你以为它的作用就这个吗?

大错特错,它还可以组合其它字符,形成特殊的元字符,可以继续整花活!

9.2 组合

​        还记得"."这个符号吗,万能匹配符,什么都可以匹配。

它其实还有好几个小弟,而这些小弟就需要和"\"组合生效。具体如下面列表所示。

符号

作用

\d

匹配任意一个数字,可以匹配0到9

\w

匹配任意一个字母、数字或下划线,可以匹配a到z,A到Z,0到9,还有"_"这个下划线。

\s

匹配任意一个空白字符,包括空格、制表符、换行符等。

\D

匹配任何一个非数字字符

\n

匹配换行符

使用示例如下,

示例一:
正则表达式:我是大内密探007
片段为:\d\d\d
结果为:007示例二:
正则表达式:我是tim,你是谁?
片段为:\w\w\w
结果为:tim

通过上面几个小弟字符,我们又多了几个可以替代字符,使用起来更灵活更精确。

但是我们可以看到上面几个替代字符有一个很大的问题,就是要么匹配0到9,要a到z,就是匹配某一个类型的所有数值,那如果我只想匹配0到5或者b到y,又或者想要匹配的字符是a,c,z之中一个,那该怎么做?

10 单字表达式——"[]"

如何让字符的匹配范围可以按照我们的要求进行?

这就要用到我们重要的字符——"[]"。

方括号表示一个字符集,可以用于匹配括号内的任何一个字符。

我们看一下示例,

示例一:
正则表达式:[6好!]
片段为:666,今天天气真的超级好!
匹配结果:6

可以看到我们,我们的正则表达式方括号中有"6","好","!",所以只要符合这三个字符都会被匹配上。

这就是方括号的作用,本质上方括号可以看做是一个指定范围的匹配字符。

那如果我们想要匹配的字符是a到u呢,如果按照目前学习的字符的话,应该要如下这样写:

示例一:
正则表达式:[abcdefghijklmnopqrstu]
片段为:今天天气真的超级好,是吧,zero。
匹配结果:e

但是这样写的话是不是太麻烦了,这么长的匹配公式,那有没有什么字符能简化这种有范围的匹配呢?

11 范围符——"-"

通过"[]"我们可以自定义匹配字符,而如果匹配的字符是有范围的话,则可以通过范围符"-"来简化表达。

我们来看几个示例:

示例一:
正则表达式:[12345678]
片段为:今天天气真的超级好,是吧,1239。
匹配结果:1示例二:
正则表达式:[1-8]
片段为:今天天气真的超级好,是吧,1239。
匹配结果:1

可以看到"[12345678]"和"[1-8]"的匹配结果是一样,也就是说如果我们的匹配字符是某一个范围的话,我们可以通过"[]"加上"-"来简化表达式。

这两个字符的组合还可以产生很多火花,如下所示,

正则表达式

作用

讲解

[a-z]

匹配所有小写字母

其中a表示字符范围的起始字符,z表示字符范围的结束字符,中括号内的字符范围可以匹配任何一个小写字母。

[0-9]

匹配所有数字

其中0表示字符范围的起始字符,9表示字符范围的结束字符,中括号内的字符范围可以匹配任何一个数字。

[A-Za-z0-9_]

匹配任何单词字符

其中A-Za-z表示所有大小写字母,0-9表示所有数字,下划线_表示下划线字符,中括号内的字符范围可以匹配任何一个单词字符。

[\x00-\x7F]

匹配所有ASCII字符

其中\x00表示ASCII字符范围的起始字符,\x7F表示ASCII字符范围的结束字符,中括号内的字符范围可以匹配任何一个ASCII字符。

看到上面的表达式是不是感觉通过“-”字符,表达式就变得简约了不少。

那如果我们想要匹配除了几个字符以外的所有字符,又该怎么做?

总不能把所有字符都列到里面去吧?

那这里就要学习我们方括号的好搭档——"^"。

12 范围反选 —— "[^]"

如果现在我们想要匹配除了a,b,d以外的所有字符,可以如下操作:

示例一:
正则表达式:[^E]
片段为:E哥,今天天气真的超级好!
匹配结果:哥

上面的"[^E]",意思是匹配除了字符"E"以外的所有字符,所以第一个匹配到的就是"哥",这就是范围反选。

也就是"[^]",匹配除了里面的所有字符。

学到这我们已经掌握了很多了,给优秀的我们鼓个掌吧。

我们学习了上面的内容,有没有发现一个问题,上面的字符都是匹配符合条件的单个字符,那如果我们要匹配特定的多个字符怎么办?

13 分组匹配符——"()"

如果我们现在要匹配的是一个片段,比如要匹配"ABABABABABAB"中的AB,我们该怎么做?

这个时候,我们可以用"()"表示我们要匹配的片段,示例如下

示例一:
正则表达式:(AB)
片段为:ABABABABAB
匹配结果:AB

通过在"()"中填写对应的字符,我们就可以匹配到符合条件的所有片段。

但是如果不用(),我们直接用"AB"也能匹配啊,如下

示例一:
正则表达式:(AB)
片段为:ABABABABAB
匹配结果:AB

是不是也可以,那我们要"()"干啥?

其实它最大的作用是分组,把多个字符当做一个完整的片段使用,我举个例子

示例一:
正则表达式:(AB)*
片段为:ABABABABAB
匹配结果:ABABABABAB示例二:
正则表达式:AB*
片段为:ABABABABAB
匹配结果:AB

我们可以看到上面示例一,是把"AB"看做一个完整片段,然后匹配数次,就把整个字符串都匹配出来了。

而"AB*"的含义就是,匹配以A开头,后面接多个B的字符串,但是字符串中只有单个B,所以匹配的结果为"AB"。

这就是加"()"的作用,把括号里面的内容视作不可分割的完整片段。

如果有啥错漏,或者还要了解的地方,可以私信我,别公开处刑,我巨脆弱玻璃心,心理承受能力-9999。

大白话说JAVA —— 正则表达式相关推荐

  1. 大白话说Java泛型:入门、使用、原理

    文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java泛型:入门.使用.原理> 远在 JDK 1.4 版本的时候,那时候是没有泛型的概念的.当时 Java 程序员们写集合类的代码都 ...

  2. 大白话说Java反射:入门、使用、原理,BAT 面试官 如何面试

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...

  3. java正则表达式课程_通过此免费课程学习正则表达式

    java正则表达式课程 by Beau Carnes 通过博卡恩斯 通过此免费课程学习正则表达式 (Learn Regular Expressions with this free course) & ...

  4. java正则表达式 1,Java正则表达式学习(1)

    Java正则表达式学习(一) 1.什么是正则表达式: 正则表达式(regular expressions) 是一种描述字符串集的方法,它是以字符串集中各种字符串的公有特征为依据的. 正则表达式可以用于 ...

  5. 孪生素数 java代码_科学网—孪生素数猜想——利用 Java + 正则表达式 输出孪生素数对 - 马廷灿的博文...

    查了一下资料,发现正则表达式竟然可以用来检查素数(http://coolshell.cn/articles/2704.html)!(由于工作需要,几年前开始接触.利用正则表达式,给工作带了很大方便,也 ...

  6. java正则表达式的用法_Java 正则表达式的使用

    Java 正则表达式的使用 1:正则表达式语法大全 字符 说明 \ 将下一字符标记为特殊字符.文本.反向引用或八进制转义符.例如,"n"匹配字符"n".&quo ...

  7. Java正则表达式--Matcher.group函数的用法

    https://www.cnblogs.com/jiafuwei/p/6080984.html Java正则表达式--Matcher.group函数的用法 原来,group是针对()来说的,group ...

  8. java 正则表达式入门(一)

    Java正则表达式 定义:具有特定规则的一种表达式语言. 作用:专门用于操作字符串,操作意味着(校验,截取).且可以简化我们对字符串的操作方式 比如,验证手机号码 如果没有正则表达式我们的过程就应该是 ...

  9. bigint对应java什么类型_「JAVA」从格式化输出到扫描输入,深究Java正则表达式匹配之道

    字符串是不可变的 字符串是不可变的,也就是说当字符串的内容发生改变的时候,会创建一个新的String对象:但是如果内容没有发生改变的时候,String类的方法会返回原字符串对象的引用. 而正则表达式往 ...

  10. Java 正则表达式使用详解

    今天研究开源项目,哆啦A梦,研究里面显示log 的原理. 后来发现,用到了正则表达式.觉得很有用,就捡起来,重新研究一下. 学习思路指导: 每一门学问,最好的深入学习方法,是去其官网,研究其说明文档. ...

最新文章

  1. Tomcat中的Session小结
  2. exce中让两列数据一一对应_表格数据对比眼花缭乱、痛苦不堪,找对方法,1秒搞定...
  3. adminlte支持html5吗,spring boot:用adminlte做前端
  4. 2.MySQL中的索引
  5. pyspark分类算法之多层感知机神经网络分类器模型实践【MLPClassifier】
  6. NOI.AC NOIP2018 全国热身赛 第四场
  7. 关于海康相机ip地址无法更改问题
  8. excel文件设置的工作表保护如何撤销
  9. MySQL Clone插件
  10. 打开Internet信息服务及IIS管理器
  11. 智能网联汽车仿真测试软件,智能网联汽车测试评价及检测认证
  12. Kylo调研总结(二)
  13. 经验10年搞不过卖烧烤的!后入阿里我软件测试是怎么学废的,这些话我想送给一事无成的自学测试们...
  14. 如何删除 Windows 10 上的 Windows.old 文件夹?
  15. ENVI 5.3 计算NDVI的几种方法及结果的差异分析
  16. 雄厚实力的企业支持,是拍账王品牌前进发展的根基
  17. NX二次开发-UFUN获取工程图所有视图tag UF_DRAW_ask_views
  18. 栈(也被称作堆栈,一种遵循先进后出原则的数据结构)
  19. 数组题目:递增的三元子序列
  20. 认识Fitnesse

热门文章

  1. wondow远程ubuntu18.04桌面
  2. 《谁的青春不迷茫》——其实我们都一样
  3. 【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(8 月 9 日论文合集)
  4. 邀请函丨飞凌嵌入式与您相约“2020慕尼黑上海电子展
  5. 每日一题dive2-week14
  6. mac安装nvm方法,以及一些安装失败的解决方法
  7. 张佑赫新专辑北京首唱 曝HOT有望借风云榜重组[转载]
  8. 万事达卡发布专利提升区块链节点激活速度
  9. Mybatis整合Spring之传统dao方法
  10. linux 运维 samba问题,Samba详解