资讯专栏INFORMATION COLUMN

正则表达式简单入门 & 实践

superw / 1737人阅读

摘要:说到邮箱格式,我们简单分析下邮箱的命名方式一般分为三部分邮件地址邮箱域名地址邮件地址部分的规则如下英文字母数字下划线中划线点举几个栗子根据以上规则,我们先写一下邮件地址部分图示没什么问题继续往下走。

前言

平时的工作中有很多地方都要用到正则表达式,不得不说,正则的表达式非常强大,比如,我们常用的jquery选择器,非常方便,jquery的源码中,选择器部分应用了大量的正则表达式。然而很多时候,当我们要用到正则的时候,很多人(也包括我 == ) 的做法都是打开百度,复制粘贴,试一下,没问题,大功告成。然而,当遇到特殊需求的时候,复制粘贴大法就不好用了,所以掌握这正则还是很有必要的。下面我就结合我的一些认识对正则进行简单的介绍,如有纰漏欢迎指出。

开胃小菜

假如有这样一道题目:

请写一个邮箱验证的正则。

如果你能写出:

    /@/

试一下:

var reg = /@/;
reg.test("xxx001@pingan.com.cn");//true

图示:

没毛病!
恭喜你,你已经会写正则了~ (滑稽脸)

其实这是阿里的一道技术面试题,可以写的很简单,也可以写的很复杂,至于写出来的是什么样,就要看个人功力了。

继续往下走。说到邮箱格式,我们简单分析下:

邮箱的命名方式一般分为三部分

邮件地址

@

邮箱域名地址

邮件地址部分的规则如下:

英文字母

数字

下划线

中划线

举几个栗子:

123456@xxx.xxx

blue.sky@xxx.xxx

123bird@xxx.xxx

ex-xxx001@xxx.xxx

根据以上规则,我们先写一下邮件地址部分:

var reg = /^w+([-+_.]w+)*$/;

    reg.test("123456"); //true
    reg.test("blue.sky"); //true
    reg.test("123bird"); //true
    reg.test("ex-xxx001"); //true

图示:

没什么问题, 继续往下走。

@ 直接用@匹配就可以了

域名地址部分的规则:

英文字母

数字

中划线

@后面的第一个字符不能是中华线和点,简单写一下:

var reg=  /^@w+([-.]w+)*.w+([-.]w+)*$/
var reg = /^@w+([-.]w+)*.w+([-.]w+)*$/;
reg.test("@123-abc.com.cn"); // true

最终的正则可以是这样子的:

var reg = /^w+([-+_.]w+)*@w+([-.]w+)*.w+([-.]w+)*$/;
reg.test("scau_kk@xxx.com.cn"); //true

图示:

到这里,一种简单的邮箱正则就写好了(zz,罗里吧嗦一大堆)。

后面就简单的总结下。

正式入门 字符类

首先介绍下最常见的,也是最基本的 -字符类 。

代码 说明 其它介绍
. 匹配除了换行符之外的任何单个字符 举个例子,在一条句子中, "nay, an apple is on the tree", .n 可以匹配anon,但是不能匹配nay ;要注意的是:一个未被转义的 . 会匹配除行结束符意以外的任何字符。
^ 匹配字符串的开始
$ 匹配字符串的结束 等同于[0-9]; 一个未转义的$匹配文本的结束。当指定了m标示时,它也能匹配行结束符。
转义字符 可以使用 来取消某些字符本身的意义,比如要想匹配.,* 可以使用 转义字符。 另外,1 是指向分组1所捕获的文本的一个引用,所以它能被再次匹配。
 匹配单词边界 字符边界是一个位置,它的前后都没有其他字符,不过匹配的单词边界并不包含在匹配中。换句话说,匹配字边界的长度为零。
s 匹配单个空白字符 包括空格、制表符、换行符、换行符。
S s 的反义,匹配空白以外的单个字符。
w 匹配任何字母数字字符包括下划线。 等同于[A-Za-z0-9_]
W 匹配任何非字符。 等同于[^A-Za-z0-9_]
d 匹配数字字符 等同于[0-9]
D 匹配非数字字符 等同于[^0-9]

对照着这个表格,上面的邮箱正则就很容易看了。

举几个简单的例子

console.log(/^w+$/.test("abc"));  //true
console.log(/^d+$/.test("12345")); //true
console.log(/^D+$/.test(" "));  //true
标示
代码 含义 用法
g global, 全局的 如果标示 g 被使用,值为true
i ignore, 大小写不敏感 如果标示 i 被使用,值为true
m multiLine, 多行查找( ^$能匹配行结束符 ) 如果标示 m 被使用,值为true
正则表达式量词

一般用来指定数量,常用的如下所示:

代码 说明
重复零次或更多次
重复1次或更多次
重复0次或更多次
{n} 重复n次
{n,} 重复大于等于n次
{n,m} 重复n到m次

举几个简单的例子

console.log(/^w{3}$/.test("abc"));  //true
console.log(/^d{1,5}$/.test("12345")); //true
分支条件

正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配。
具体方法是用|把不同的规则分隔开。

我们来看看个具体的例子:

var reg =  /0d{2}-d{8}|0d{3}-d{7}/;

这个表达式能匹配两种以连字号分隔的电话号码:

一种是3位区号,8位本地号(如010-12345678),
一种是4位区号,7位本地号(0755-1234567)。

或者写一个简单的匹配手机号码的正则:

var reg =  /^1(3|4|5|7|8)[0-9]d{8}$/;
分组

我们已经知道了如何重复单个字符,但如果想要重复多个字符又该怎么办呢?
这时候就可以使用分组了。

分组的类型有四种:

代码 用法 介绍
捕获型 () 一个捕获刑分组是一个被包围在圆括号里的正则表达式分支,任何匹配这个分组的字符都会被捕获。每个捕获型分组都被指定了一个数字。在正则表达式中第一个捕获的(是分组1,第二个捕获(的是是分组2。
非捕获型 (?:前缀) 非捕获型分组仅做简单的匹配,并不会捕获匹配的文本。
向前正向匹配 (?=前缀) 向前正向匹配类似于非捕获型分组,但在这个组匹配之后,文本会倒回到它开始的地方,实际上并不匹配任何东西。
向前负向匹配 (?!前缀) 向前负向匹配类似于向前正向匹配分组,但只有当它匹配失败的时候才继续向前进行匹配。

举个简单的例子:

实现一个验证ip地址的正则:

var reg = /^((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)$/;

reg.test("127.0.0.1"); // true
reg.test("255.255.888.888"); // false

结合图示:

集合图示就很清晰了。

上面的部分只是正则表达式很小的一部分,篇幅有限,下一篇再做介绍。
那根据上面出现的内容,我们看一个更复杂的例子来巩固,摘自精粹,一起来看下。

一个复杂的例子
var parse_url = /^(?:([A-Za-z]+):)?(/{0,3})([0-9.-A-Za-z]+)(?::(d+))?(?:/([^?#]*))?(?:?([^#]*))?(?:#(.*))?$/;

var  result = parse_url.exec(url);

names.forEach(function(item, index){ 
    console.log(item + ": " + result[index]);
});

console.log(result);
 // url: http://www.ora.com:80/goodparts?q#fragement
 // scheme: http
 // slash: //
 // host: www.ora.com
 // port: 80
 // path: goodparts
 // query: q
 // hash: fragement
 

是不是感觉萌萌哒(滑稽脸.jpg)

看看图:

我们来分解下parse_url,看它到底是怎么工作的。

首先是 ^, 表示字符串的开始。它是一个锚,指引exec不要跳过那些不像url的前缀,只匹配那些从开头就像url一样的字符串。

scheme
var reg = (?:([A-Za-z]+):)

这个因子匹配一个协议名,当且仅当后面跟随一个:的时候才匹配。

(?...) 表示一个非捕获型分组。
后缀? 表示这个分组是可选的。

第一个捕获型分组的编号是1,所以该匹配的结果会出现在result[1]中。

slash
var reg = (/{0,3});

下一个因子是捕获刑分组2,这里需要对 / 进行转义,这样就不会被解释为结束符。
{0,3}表示 斜杠 / 会被匹配 0次 或者1~3次。

host
var reg = ([0-9.-A-Za-z]+);

这第三个捕获型分组是是主机名. 由 一个或多个数字,字母, ., - 组成.
这里需要对-进行转义。

port
var reg = (::(d+))?;

这第四个捕获型分组是端口号。它是由一个前置:加上一个或多个数字而组成的序列。

path
var reg = (?:/([^?#]*))?;

这个是另一个可选的分组,以一个/`开始。之后的字符类[^?#] 以一个^ 开始,表示这个类包含除? # 之外的所有字符。*表示匹配0次 或多次。

query
var reg = (?:?([^#]*))?;

这个还是一个可选分组,以一个?`开始,它包含了一个捕获型分组,这个分组包含 0个 或多个 非 #的字符。

hash
var reg = (?:#(.*))?;

这是最后一个可选分组,以一个#`开始, . 会匹配除换行符以外的所有字符。

最后的$表示字符串的结束,它保证这个url的尾部没有其他更多内容了。

以上便是parse_url的所有因子了。

这个正则表达式还可以写的更复杂,但通常不推荐这么做。

再举个例子:

var url = "http://www.ora.com:80/goodparts?q#fragement";
 var result = url.split(/^(([^:/?#]+):)?((//)?([^/?#]*))?([^?#]*)(?([^#]*))?(#(.*))?/);
 console.log(result);

短小精悍的正则表达式是最好的。

作为基础入门的介绍,写到这里就差不多了,后续内容后续会继续发布。

本大汪差不多也该收拾东西,明天回家~预祝大家?年大吉。

附文中出现的可视化工具

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81367.html

相关文章

  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • TRY REGEX:正则达式交互式入门教程 翻译&解答

    摘要:写一个正则表达式来测试变量中是否包含字符串。用函数给出不使用字符,但和等价的正则表达式。第十四课标志全局匹配标志第二个常用的标志是全局匹配标志,用字母表示。写出一个正则表达式来检验合法性。非捕获组的主要用途是给一个组赋予量词。 TRY REGEX 是一个交互式的正则表达式学习项目项目地址:https://github.com/callumacra...在线地址:http://tryre...

    李义 评论0 收藏0
  • 正则达式入门实践(一)

    摘要:一前言正则表达式入门实践系列文章适合熟悉至少使用过正则表达式的同学,在文章开始的时候我们都会带着问题去思考如何正确应用正则表达式解决出现的问题,在解决问题的过程中增长你的知识,提高你的实践能力。 一 前言 正则表达式入门实践系列文章适合熟悉至少使用过正则表达式的同学,在文章开始的时候我们都会带着问题去思考如何正确应用正则表达式解决出现的问题,在解决问题的过程中增长你的知识,提高你的实践...

    chanthuang 评论0 收藏0
  • 机器学习 面试常见问题&答案 ①

    摘要:解决模型退化问题避免了过渡训练后,导致模型准确率反而降低的情况。经过实验后发现确实能解决这个问题。本人对于这个问题的确切原因并不清楚,但是猜测这个原因很可能是由于梯度消失以及众多其他原因所造成的。 给定卷积神经网络输入,卷积核大小,padding,步长,求输出的shape?showImg(https://segmentfault.com/img/remote/146000001781...

    Tangpj 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<