专栏首页code秘密花园还不会正则表达式?看这篇!

还不会正则表达式?看这篇!

正则表达式是很多程序员,甚至是一些有了多年经验的开发者薄弱的一项技能。大家都很多时候都会觉得正则表达式难记、难学、难用,但不可否认的是正则表达式是一项很重要的技能,所有我将学习和使用正则表达式时的关键点整理如下,供大家参考。

不同语言中的正则表达式写法有少许差异,本文将使用Javascript中的语法。

什么是正则表达式?

正则表达式(Regular ExpressionRegex),是用于定义某种特定搜索模式的字符组合。正则表达式可用于匹配、查找和替换文本中的字符,进行输入数据的验证,查找英文单词的拼写错误等。

调试工具

下面列出了几款优秀的在线调试工具,如果你想创建或者调试正则表达式可能会需要。个人比较偏好Regex101regex101支持在正则表达式的不同flavor之间切换、解释你的正则表达式、显示匹配信息、提供常用语法参考等功能,非常强大。

  • Regex101
  • Regexr
  • Regexpal

开始

Javascript中,一个正则表达式以 / 开头和结尾,所以简单至 /hello regexp/ 就是一个正则表达式。

Flags(标志符或修饰符)

Flags写在结束的/之后,可以影响整个正则表达式的匹配行为。常见的flags有:

  • g:全局匹配(global);正则表达式默认只会返回第一个匹配结果,使用标志符g则可以返回所有匹配
  • i:忽略大小写(case-insensitive);在匹配时忽略英文字母的大小写
  • m:多行匹配(multiline);将开始和结束字符(^$)视为在多行上工作,即分别匹配每一行(由 \n\r 分割)的开始和结束,而不只是只匹配整个输入字符串的最开始和最末尾处

Flags可以组合使用,如:

Character Sets(字符集合)

用于匹配字符集合中的任意一个字符,常见的字符集有:

  • [xyz]:匹配"x"或"y""z"
  • [xyz]:补集,匹配除 "x" "y" "z"的其他字符
  • [a-z]:匹配从 "a""z" 的任意字符
  • [^a-n]:补集,匹配除"a""n"的其他字符
  • [A-Z]:匹配从 "A""Z" 的任意字符
  • [0-9]:匹配从 "0""9" 的任意数字

比如匹配所有的字母和数字可以写成:/[a-zA-Z0-9]/ 或者 /[a-z0-9]/i

Quantifiers (量词)

在实际使用中,我们常常需要匹配同一类型的字符多次,比如匹配11位的手机号,我们不可能将 [0-9]11遍,此时我们可以使用Quantifiers来实现重复匹配。

-{n}:匹配 n 次 -{n,m}:匹配 n-m

  • {n,}:匹配 >=n
  • ?:匹配 0 || 1
  • *:匹配 >=0 次,等价于 {0,}
  • +:匹配 >=1 次,等价于 {1,}

Metacharacters(元字符)

在正则表达式中有一些具有特殊含义的字母,被称为元字符,简言之,元字符就是描述字符的字符,它用于对字符表达式的内容、转换及各种操作信息进行描述。

常见的元字符有:

  • \d:匹配任意数字,等价于 [0-9]
  • \D:匹配任意非数字字符;\d 的补集
  • \w:匹配任意基本拉丁字母表中的字母和数字,以及下划线;等价于 [A-Za-z0-9_]
  • \W:匹配任意非基本拉丁字母表中的字母和数字,以及下划线;\w 的补集
  • \s:匹配一个空白符,包括空格、制表符、换页符、换行符和其他Unicode空格
  • \S:匹配一个非空白符;\s的补集
  • \b:匹配一个零宽单词边界,如一个字母与一个空格之间;例如,/\bno/ 匹配 "at noon" 中的 "no"/ly\b/ 匹配 "possibly yesterday." 中的 "ly"
  • \B:匹配一个零宽非单词边界,如两个字母之间或两个空格之间;例如,/\Bon/ 匹配 "at noon" 中的 "on"/ye\B/ 匹配 "possibly yesterday." 中的 "ye"
  • \t:匹配一个水平制表符(tab)
  • \n:匹配一个换行符(newline)
  • \r:匹配一个回车符(carriage return)

Special Characters (特殊字符)

正则中存在一些特殊字符,它们不会按照字面意思进行匹配,而有特殊的意义,比如前文讲过用于量词的?、*、+。其他常见的特殊字符有:

  • \:转义字符,可以将普通字符转成特殊字符。比如 \w;也可以将特殊字符转成字面意思,比如 \+ 匹配 "+"
  • .:匹配任意单个字符,但是换行符除外:\n, \r, \u2028\u2029;在字符集中([.]),无特殊含义,即表示 '.' 的字面意思
  • |:替换字符(alternate character),匹配 | 前或后的表达式。比如需要同时匹配 "bear""pear",可以使用 /(b|p)ear/ 或者 /bear|pear/;但是不能用 /b|pear/,该表达式只能匹配"b""pear"
  • ^:匹配输入的开始。比如,/^A/ 不匹配 "an Apple" 中的 "A",但匹配 "An apple" 中的"A"
  • $:匹配输入的结尾。比如,/t$/ 不匹配 "eater" 中的 "t",但匹配 "eat" 中的 "t"^$ 在表单验证时常需要使用,因为需要验证从开始到结尾的一个完整输入,而不是匹配输入中的某一段

Groups(分组)

  • (xyz):捕获分组(Capturing Group),匹配并捕获匹配项;例如,/(foo)/匹配且捕获 "foo bar."中的"foo"。被匹配的子字符串可以在结果数组的元素 [1], …, [n] 中找到,或在被定义的 RegExp 对象的属性 $1, …, $9中找到 -(?:xyz):非捕获分组(Non-capturing Group),匹配但不会捕获匹配项;匹配项不能再次被访问到
  • \nn 是一个正整数,表示反向引用(back reference),指向正则表达式中第n个括号(从左开始数)中匹配的子字符串;例如,/apple(,)\sorange\1/ 匹配 "apple, orange, cherry, peach." 中的 "apple,orange,"

Assertion(断言)

  • x(?=y):仅匹配被y跟随的x;例如,/bruce(?=wayne)/,如果"bruce"后面跟着wayne,则匹配之。/bruce(?=wayne|banner)/,如果"bruce"后面跟着"wayne"或者banner,则匹配之。但是,"wayne""banner" 都不会在匹配结果中出现
  • x(?!y):仅匹配不被y跟随的x;例如,/\d+(?!.)/ 只会匹配不被 "." 跟随的数字。

/\d+(?!\.)/.exec('3.141') 匹配 "141",而不是 "3.141"

应用

上面罗列出了这么多正则表达式的语法和规则,可以在一定程度上帮助我们分析和理解一段正则表达式的作用,但是如何将这些规则组合并创造出有特定作用的表达式还需要我们自己多加练习,下面举几个例子来说明运用这些规则。

1. 匹配手机号码

我们先从比较简单的匹配手机号码开始。目前国内的手机号码是1(3/4/5/7/8)开头的11位数字,因此手机号码的正则可以分解为以下几部分:

  • 1 开头:/^1/
  • 2位为3、4、5、7、8中的一个:/[34578]//(3|4|5|7|8)/
  • 剩余3-11位均为数字,并以数字结尾:/\d{9}$/ 组合起来即为/^1[34578]\d{9}$//^1(3|4|5|7|8)\d{9}$/,因为使用捕获括号存在性能损失,所以推荐使用第一种写法。

2. 匹配电子邮件

标准的电子邮件组成为 <yourname>@<domain>.<extension><optional-extension>

每部分的格式标准为(进行了相应的简化,主要为展示如何书写正则):

  • yourname:任意英文字母(a-z/A-Z)、数字(0-9)、下划线(_)、英文句点(.)、连字符(-),长度大于0
  • domain:任意英文字母(a-z/A-Z)、数字(0-9)、连字符(-),长度大于0
  • extension:任意英文字母(a-z/A-Z),长度2-8
  • optional-extension:"."开头,后面跟任意英文字母(a-z/A-Z),长度2-8,可选 每部分的正则表达式为:
  • yourname/[a-z\d._-]+/
  • domain/[a-z\d-]+/ -extension/[a-z]{2,8}/
  • optional-extension/(.[a-z]{2,8})?/

组合起来形成最后的正则表达式:/^([a-z\d._-]+)@([a-z\d-]+)\.([a-z]{2,8})(\.[a-z]{2,8})?$/;为了增加可读性可以将每部分用"()"包起来,并不要忘记起始和结束符 ^$

原文:https://segmentfault.com/a/1190000018489883 本文由作者 MudOnTire 授权转载

本文分享自微信公众号 - code秘密花园(code_mmhy),作者:MudOnTire

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 两个你必须要重视的 Chrome 80 策略更新!!!

    Chrome 80 版本在 2020年2月份 正式发布了,随后又陆续更新了几个小版本,本次升级主要是更新了安全修复和稳定性改进以及用户体验优化。

    ConardLi
  • 正则表达式30分钟入门教程

    30分钟内让你明白正则表达式是什么,并对它有一些基本的了解,让你可以在自己的程序或网页里使用它。

    ConardLi
  • Airbnb JavaScript 风格指南(一)

    ConardLi
  • python中正则表达式的学习

    我们以match_str=”abcdefghc“、pattern=”a.*c”例,

    菜鸟小白的学习分享
  • 图匹配 科普

    匹配:在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点。

    double
  • Java正则表达式匹配日期及基本使用

    在 Java 中,\\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。

    AlbertYang
  • 正则表达式符号代表的意义

    无邪Z
  • 正则表达式

    特殊符号(使用需要'\'转义) ! $ ^ * + = | . ? \ / ( ) [ ] { } 创建正则表达式 方法一  var re =new RegEx...

    小古哥
  • 正则表达式

    正则表达式 什么是正则表达式? 正则表达式,又称规则表达式,英文名为Regular Expression,在代码中常简写为regex、regexp或RE,是计算...

    新人小试
  • 正则表达式全部符号解释

    悟空聊架构

扫码关注云+社区

领取腾讯云代金券