字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
所以我们判断一个字符串是否是合法的Email的方法是:
1.创建一个匹配Email的正则表达式;
2.用该正则表达式去匹配用户的输入来判断是否合法。
因为正则表达式也是用字符串表示的,所以,我们要首先了解如何用字符来描述字符。
在正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配一个数字,\w可以匹配一个字母或数字,所以:
.可以匹配任意字符,所以:
要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:
来看一个复杂的例子:\d{3}\s+\d{3,8}。
我们来从左到右解读一下:
1.\d{3}表示匹配3个数字,例如'010';
2.\s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' ','\t\t'等;
3.\d{3,8}表示3-8个数字,例如'1234567'。
综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。
如果要匹配'010-12345'这样的号码呢?由于'-'是特殊字符,在正则表达式中,要用'\'转义,所以,上面的正则是\d{3}\-\d{3,8}。
但是,仍然无法匹配'010 - 12345',因为带有空格。所以我们需要更复杂的匹配方式。
进阶
要做更精确地匹配,可以用[]表示范围,比如:
A|B可以匹配A或B,所以(J|j)ava(S|s)cript可以匹配'JavaScript'、'Javascript'、'javaScript'或者'javascript'。
^表示行的开头,^\d表示必须以数字开头。
$表示行的结束,\d$表示必须以数字结束。
你可能注意到了,js也可以匹配'jsp',但是加上^js$就变成了整行匹配,就只能匹配'js'了。
RegExp
有了准备知识,我们就可以在JavaScript中使用正则表达式了。
JavaScript有两种方式创建一个正则表达式:
第一种方式是直接通过/正则表达式/写出来,第二种方式是通过new RegExp('正则表达式')创建一个RegExp对象。
两种写法是一样的:
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');
re1; // /ABC\-001/
re2; // /ABC\-001/
注意,如果使用第二种写法,因为字符串的转义问题,字符串的两个\\实际上是一个\。
先看看如何判断正则表达式是否匹配:
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
RegExp对象的test()方法用于测试给定的字符串是否符合条件。
切分字符串
用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:
'a b c'.split(' '); // ['a', 'b', '', '', 'c']
嗯,无法识别连续的空格,用正则表达式试试:
'a b c'.split(/\s+/); // ['a', 'b', 'c']
无论多少个空格都可以正常分割。加入,试试:
'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']
再加入;试试:
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。
分组
除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。比如:
^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null
如果正则表达式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来。
exec()方法在匹配成功后,会返回一个Array,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。
exec()方法在匹配失败时返回null。
提取子串非常有用。来看一个更凶残的例子:
var re = /^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$/;
re.exec('19:05:30'); // ['19:05:30', '19', '05', '30']
这个正则表达式可以直接识别合法的时间。但是有些时候,用正则表达式也无法做到完全验证,比如识别日期:
var re = /^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$/;
对于'2-30','4-31'这样的非法日期,用正则还是识别不了,或者说写出来非常困难,这时就需要程序配合识别了。
贪婪匹配
需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0:
var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', '']
由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。
必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:
var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']
全局搜索
JavaScript的正则表达式还有几个特殊的标志,最常用的是g,表示全局匹配:
var r1 = /test/g;
// 等价于:
var r2 = new RegExp('test', 'g');
全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:
var s = 'JavaScript, VBScript, JScript and ECMAScript'; var re=/[a-zA-Z]+Script/g; // 使用全局匹配: re.exec(s); // ['JavaScript'] re.lastIndex; // 10 re.exec(s); // ['VBScript'] re.lastIndex; // 20 re.exec(s); // ['JScript'] re.lastIndex; // 29 re.exec(s); // ['ECMAScript'] re.lastIndex; // 44 re.exec(s); // null,直到结束仍没有匹配到
全局匹配类似搜索,因此不能使用/^...$/,那样只会最多匹配一次。
正则表达式还可以指定i标志,表示忽略大小写,m标志,表示执行多行匹配。
小结
正则表达式非常强大,要在短短的一节里讲完是不可能的。要讲清楚正则的所有内容,可以写一本厚厚的书了。如果你经常遇到正则表达式的问题,你可能需要一本正则表达式的参考书。
练习
请尝试写一个验证Email地址的正则表达式。版本一应该可以验证出类似的Email:
# js
# RegExp
# 浅谈JS正则表达式的RegExp对象和括号的使用
# JavaScript replace new RegExp使用介绍
# 详解JavaScript正则表达式之RegExp对象
# javascript正则表达式和字符串RegExp and String(一)
# JavaScript通过RegExp实现客户端验证处理程序
# javascript 中String.match()与RegExp.exec()的区别说明
# JS正则中的RegExp对象对象
# 正则表达式
# 下划线
# 切分
# 最多
# 的是
# 创建一个
# 就可以
# 一本
# 判断是否
# 可以直接
# 第二种
# 更精确
# 是一个
# 进阶
# 几个
# 如果你
# 是一种
# 还可以
# 第一个
# 则是
相关文章:
建站之星好吗?新手能否轻松上手建站?
建站之星代理费用多少?最新价格详情介绍
中山网站推广排名,中山信息港登录入口?
如何通过NAT技术实现内网高效建站?
焦点电影公司作品,电影焦点结局是什么?
5种Android数据存储方式汇总
定制建站模板如何实现SEO优化与智能系统配置?18字教程
宝塔面板创建网站无法访问?如何快速排查修复?
如何快速搭建高效可靠的建站解决方案?
魔毅自助建站系统:模板定制与SEO优化一键生成指南
如何在建站宝盒中设置产品搜索功能?
制作充值网站的软件,做人力招聘为什么要自己交端口钱?
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
C++时间戳转换成日期时间的步骤和示例代码
西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?
建站上传速度慢?如何优化加速网站加载效率?
北京网站制作的公司有哪些,北京白云观官方网站?
音乐网站服务器如何优化API响应速度?
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
建站之星2.7模板:企业网站建设与h5定制设计专题
建站之星与建站宝盒如何选择最佳方案?
如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?
公司网站制作需要多少钱,找人做公司网站需要多少钱?
如何选择适配移动端的WAP自助建站平台?
韩国服务器如何优化跨境访问实现高效连接?
建站之星备案流程有哪些注意事项?
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
建站主机系统SEO优化与智能配置核心关键词操作指南
建站为何优先选择香港服务器?
建站之星如何开启自定义404页面避免用户流失?
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
如何在香港服务器上快速搭建免备案网站?
自助网站制作软件,个人如何自助建网站?
如何用花生壳三步快速搭建专属网站?
制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?
香港服务器选型指南:免备案配置与高效建站方案解析
开封网站制作公司,网络用语开封是什么意思?
建站主机选购指南:核心配置优化与品牌推荐方案
建站主机无法访问?如何排查域名与服务器问题
实例解析Array和String方法
网站制作报价单模板图片,小松挖机官方网站报价?
个人摄影网站制作流程,摄影爱好者都去什么网站?
如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法
jQuery 常见小例汇总
制作旅游网站html,怎样注册旅游网站?
,交易猫的商品怎么发布到网站上去?
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
怎么将XML数据可视化 D3.js加载XML
高性价比服务器租赁——企业级配置与24小时运维服务
*请认真填写需求信息,我们会在24小时内与您取得联系。