!
也想出现在这里? 联系我们
广告位

你是如何学会正则表达式的?

正则表达式在几乎所有语言中都可以使用,无论是前端的 JavaScript、还是后端的 Java、c#。他们都提供相应的接口/函数支持正则表达式。但很神奇的是:无论你大学选择哪一门计算机语言,都没有关于正则表达式的课程给你修,在你学会正则之前,你只能看着那些正则大师们,写了一串外星文似的字符串,替代了你用一大篇幅的 if else 代码来做一些数据校验。既然喜欢,那就动手学呗,可当你百度出一一堆相关资料时,你发现无一不例外的枯燥至极,难以学习。本文旨在用最通俗的语言讲述最枯燥的基本知识!

正则基础知识点:

1.元字符
万物皆有缘,正则也是如此,元字符是构造正则表达式的一种基本元素,我们先来记几个常用的元字符:

有了元字符之后,我们就可以利用这些元字符来写一些简单的正则表达式了,比如:

匹配有 abc 开头的字符串:
\babc 或者^abc
匹配 8 位数字的 QQ 号码:
^\d\d\d\d\d\d\d\d$
匹配 1 开头 11 位数字的手机号码:
^1\d\d\d\d\d\d\d\d\d\d$
2. 重复限定符

有了元字符就可以写不少的正则表达式了,但细心的你们可能会发现:别人写的正则简洁明了,而不理君写的正则一堆乱七八糟而且重复的元字符组成的。正则没提供办法处理这些重复的元字符吗?答案是有的!为了处理这些重复问题,正则表达式中一些重复限定符,把重复部分用合适的限定符替代,下面我们来看一些限定符:

有了这些限定符之后,我们就可以对之前的正则表达式进行改造了,比如:

匹配 8 位数字的 QQ 号码:
^\d{8}$
匹配 1 开头 11 位数字的手机号码:
^1\d{10}$
匹配银行卡号是 14~18 位的数字:
^\d{14,18}$
匹配以 a 开头的,0 个或多个 b 结尾的字符串
^ab*$
3. 分组
从上面的例子(4)中看到,限定符是作用在与他左边最近的一个字符,那么问题来了,如果我想要 ab 同时被限定那怎么办呢?正则表达式中用小括号()来做分组,也就是括号中的内容作为一个整体。因此当我们要匹配多个 ab 时,我们可以这样。如匹配字符串中包含 0 到多个 ab 开头:
^(ab)*
4. 转义
我们看到正则表达式用小括号来做分组,那么问题来了。如果要匹配的字符串中本身就包含小括号,那是不是冲突?应该怎么办?
针对这种情况,正则提供了转义的方式,也就是要把这些元字符、限定符或者关键字转义成普通的字符,做法很简答,就是在要转义的字符前面加个斜杠,也就是即可。如:要匹配以(ab)开头:
^(\(ab\))*
5. 条件或
回到我们刚才的手机号匹配,我们都知道:国内号码都来自三大网,它们都有属于自己的号段,比如联通有 130/131/132/155/156/185/186/145/176 等号段,假如让我们匹配一个联通的号码,那按照我们目前所学到的正则,应该无从下手的,因为这里包含了一些并列的条件,也就是“或”,那么在正则中是如何表示“或”的呢?正则用符号 | 来表示或,也叫做分支条件,当满足正则里的分支条件的任何一种条件时,都会当成是匹配成功。那么我们就可以用或条件来处理这个问题:
^(130|131|132|155|156|185|186|145|176)\d{8}$
6. 区间
看到上面的例子,是不是看到有什么规律?是不是还有一种想要简化的冲动?实际是有的。正则提供一个元字符中括号 [] 来表示区间条件。

限定 0 到 9 可以写成[0-9]
限定 A-Z 写成[A-Z]
限定某些数字 [165]

那上面的正则我们还改成这样:
^((13[0-2])|(15[56])|(18[5-6])|145|176)\d{8}$
好了,正则表达式的基本用法就讲到这里了,其实它还有非常多的知识点以及元字符,我们在此只列举了部分元字符和语法来讲,旨在给那些不懂正则或者想学正则但有看不下去文档的人做一个快速入门级的教程,看完本教程,即使你不能写出高大上的正则,至少也能写一些简单的正则或者看得懂别人写的正则了。

正则进阶知识点:

1. 零宽断言
无论是零宽还是断言,听起来都古古怪怪的,那先解释一下这两个词。

1、断言:俗话的断言就是“我断定什么什么”,而正则中的断言,就是说正则可以指明在指定的内容的前面或后面会出现满足指定规则的内容,意思正则也可以像人类那样断定什么什么,比如"ss1aa2bb3",正则可以用断言找出 aa2 前面有 bb3,也可以找出 aa2 后面有 ss1.

2、零宽:就是没有宽度,在正则中,断言只是匹配位置,不占字符,也就是说,匹配结果里是不会返回断言本身。

意思是讲明白了,那他有什么用呢?我们来举个栗子:假设我们要用爬虫抓取 csdn 里的文章阅读量。通过查看源代码可以看到文章阅读量这个内容是这样的结构:
"阅读数:641"
其中也就‘641’这个是变量,也就是说不同文章不同的值,当我们拿到这个字符串时,需要获得这里边的‘641’有很多种办法,但如果正则应该怎么匹配呢?下面先来讲几种类型的断言:

正向先行断言(正前瞻):
语法:(?=pattern)
作用:匹配 pattern 表达式的前面内容,不返回本身。

这样子说,还是一脸懵逼,好吧,回归刚才那个栗子,要取到阅读量,在正则表达式中就意味着要能匹配到‘’前面的数字内容。按照上所说的正向先行断言可以匹配表达式前面的内容,那意思就是:(?=) 就可以匹配到前面的内容了。匹配什么内容呢?如果要所有内容那就是:

  1. String reg=".+(?=</span>)";
  2. String test = "<span class=\"read-count\">阅读数:641</span>";
  3. Pattern pattern = Pattern.compile(reg);
  4. Matcher mc= pattern.matcher(test);
  5. while(mc.find()){
  6. System.out.println("匹配结果:")
  7. System.out.println(mc.group());
  8. }
  9. //匹配结果:
  10. //<span class="read-count">阅读数:641

可是老哥我们要的只是前面的数字呀,那也简单咯,匹配数字 d,那可以改成:

  1. String reg="\\d+(?=</span>)";
  2. String test = "<span class=\"read-count\">阅读数:641</span>";
  3. Pattern pattern = Pattern.compile(reg);
  4. Matcher mc= pattern.matcher(test);
  5. while(mc.find()){
  6. System.out.println(mc.group());
  7. }
  8. //匹配结果:
  9. //641

大功告成!

正向后行断言(正后顾)
语法:(?

  1. //(?<=<span class="read-count">阅读数:)\d+
  2. String reg="(?<=<span class=\"read-count\">阅读数:)\\d+";
  3. String test = "<span class=\"read-count\">阅读数:641</span>";
  4. Pattern pattern = Pattern.compile(reg);
  5. Matcher mc= pattern.matcher(test);
  6. while(mc.find()){
  7. System.out.println(mc.group());
  8. }
  9. //匹配结果:
  10. //641

给TA打赏
共{{data.count}}人
人已打赏
前端学习

半小时学会正则表达式(下)

2024-7-17 17:48:26

前端学习

HTML5 placeholder美化input背景提示文字

2024-7-19 14:48:37

下载说明

  • 1、微码盒所提供的压缩包若无特别说明,解压密码均为weimahe.com
  • 2、下载后文件若为压缩包格式,请安装7Z软件或者其它压缩软件进行解压;
  • 3、文件比较大的时候,建议使用下载工具进行下载,浏览器下载有时候会自动中断,导致下载错误;
  • 4、资源可能会由于内容问题被和谐,导致下载链接不可用,遇到此问题,请到文章页面进行反馈,以便微码盒及时进行更新;
  • 5、其他下载问题请自行搜索教程,这里不一一讲解。

站长声明

本站大部分下载资源收集于网络,只做学习和交流使用,版权归原作者所有;若为付费资源,请在下载后24小时之内自觉删除;若作商业用途,请到原网站购买;由于未及时购买和付费发生的侵权行为,与本站无关。本站发布的内容若侵犯到您的权益,请联系本站删除,我们将及时处理!
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索