JS-正则表达式实战篇(Angel著)
JS-正则表达式实战篇(Angel著)
大家会看到我最新的系列博客都是spring boot怎么突然来了一个js的呢,而且这个貌似对大家而言好像很简单的嘛,所以在写之前我说说我写这一篇文章的初衷。公司新来了一位同事,然后问我什么js正则表达式?我当时也是脑袋一蒙,自己平时会用,但是要下个定义还是有点困难的,然后脑袋在一转,好像自己也忘记的差不多了,所以这一篇文章主要是为了同事而写的,希望他能对js以及对正则表达式有一定新的认识。
这里主要分如下几节:
2. js之Hello World
3. js正则表达式理论
4、正则实战学习
(1)小试牛刀
(2)初露锋芒
初露锋芒之【手机号码】正则表达式
初露锋芒之【邮箱】正则表达式
(3)过关斩将
1. 什么是JS?
在学习js正则表达式的时候,这里我们抛砖引玉下:什么是js?首先js的全称是JavaScript,是一种脚本语言,一种广泛用于客户端web开发的脚本语言,常用来给HTML网页标签的元素添加动态功能。这里有一个关键是js是用于客户端的web脚本语言那么他和现在流行的java语言是什么关系呢?很多刚刚了解javaScript的初学者都会有这种误区觉得是是不是java的扩展语言或者跟java有一定的联系呢,并且java是服务端语言。
到底有联系呢?博主在这里告诉大家没有关系?JavaScript本来叫LiveScript,在Netscape Navigator 2正式发布前夕,Netscape为了更搭上媒体热炒的java顺风车,所以改名叫javascript。另外一个解释就是Netscape与Sun合作,Netscape管理层希望它外观看起来更像java,因此取名为javaScript。不管是什么一个理解,总之javaScript和Java没有关系,请大家牢记。
2. js之Hello World
这是本博主第一次写有关JS相关的文章,虽然是介绍正则表达式,但是在这里也帮大家回顾下js的和hello world吧。我们在学习任何一门语言的时候,第一个代码少不了Hello World,那么在JS中是如何实现呢?具体需要如下几个步骤:
(1) 新建一个.html文件;
(2) 编写script语言;
(3) 测试;
(1)新建一个.html文件;
我们使用记事本或者常用的开发工具Dreamweaver等新建一个hello.html
在这个文件中有一个按钮元素,具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="button" value="点击我哦" />
</body>
</html>
以上这个代码很简单,没有什么特别的,当然这是在你会html的情况下,如果html不了解的话,那么博主建议先回去学习下什么是html吧,然后也可以html5。
(2)新建script脚本语言
Javascript的使用方式常用的有两种,第一就是在.html中使用标签<script>标签是脚本语言,其二就是使用<script src=”xxx.js”>的方式引入外部定义的js文件,这里既然是hello world我们就使用最简单的方式来进行编码,直接在hello.html中进行编码,具体代码如下:
<!--
作者:412887952@qq.com
时间:2016-04-30
描述:使用script标签指定这里的代码是脚本语言。
开发中我们常常会把脚本代码放在一个定义的.js文件中,然后通过script src
引入的方式进行编码,当然如果脚本代码就一两句,也没有必要非得创建一个.js
文件进行引入,这个反而是画蛇添足了。
-->
<script>
/*
* 这是js的注释方式。
* 使用function关键词定义这是一个方法,方法可以和我们定义的标签元素
* 进行绑定,在标签元素中都一个 onclick的方法,我们直接绑定,就会执行我们
*
* 定义的js方法了。
*
*
*/
function hello(){
alert("welcome to js!");
}
</script>
接在在input标签进行绑定我们编写的脚本语言:
<input type="button" value="点击我哦" onclick="hello()" />
这里使用onclick属性和我们编写的js的hello进行绑定。
这里是所有的代码(直接复制到.html文件双击就可以运行):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="button" value="点击我哦" onclick="hello()" />
<!--
作者:412887952@qq.com
时间:2016-04-30
描述:使用script标签指定这里的代码是脚本语言。
开发中我们常常会把脚本代码放在一个定义的.js文件中,然后通过script src
引入的方式进行编码,当然如果脚本代码就一两句,也没有必要非得创建一个.js
文件进行引入,这个反而是画蛇添足了。
-->
<script>
/*
* 这是js的注释方式。
* 使用function关键词定义这是一个方法,方法可以和我们定义的标签元素
* 进行绑定,在标签元素中都一个 onclick的方法,我们直接绑定,就会执行我们
*
* 定义的js方法了。
*
*
*/
function hello(){
alert("welcome to js!");
}
</script>
</body>
</html>
(3)测试
到这里hello js就完成了。我们使用浏览器打开我们编写的代码,即可按钮即可看到welcome to js! 的弹框信息。好了这里我们不是要介绍js的hello world的,还是让我们来看看什么是js正则表达式吧,这个前提就是对js有都一定了解了,不然是会学着很累的。
3. js正则表达式实战
(1)Js正则表达式定义?
在回答js正则表达式的时候,我们先说说什么是正则表达式?所谓的正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)是对字符串操作的一种逻辑公式,就是事先定义好的一些特殊字符、及一些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
了解了正则表达式我们就可以很好的理解什么是js正则表达式了?就是使用js脚本语言实现的可以匹配规则字符串的表达式。
(2)正则表达式语法:
一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
(3)正则表达式的创建
var re = new RegExp();//RegExp是一个对象,和Aarray一样
//但这样没有任何效果,需要将正则表达式的内容作为字符串传递进去
re =new RegExp("a");//最简单的正则表达式,将匹配字母a
re=new RegExp("a","i");//第二个参数,表示匹配时不分大小写
正则表达式还有另一种正则表达式字面量的声明方式
var re = /a/gi;
我们常用的是第二种方式,因为第一种方式中是使用“”包含的方式,这样在有特殊字符的时候要使用使用字符字符的方式进行转义,当然这里只是建议,要是喜欢第一种方式也未曾不可。
(4)正则表达式的方式、属性
其中将对正则表达式的常用方法和属性,以及相关的String的match方法讲述。
正则表达式方法:
· test 方法:返回Boolean型。它指出被查找的字符串中是否包含该模式。如果存在返回True,否则返回False;
· exec 方法:用正则表达式模式在字符串中寻找,并返回符合该正则表达式模式的数组;
正则表达式属性:
· source 属性:返回正则表达式的文本内容。只读;
String 的匹配正则表达式的方法:
· match 方法:找到一个或多个正则表达式的匹配,类似exec 方法,返回一数组
4、正则实战学习
说了这么多理论无非就是为了使用,我们还是来练练手吧。
(1)小试牛刀
//最简单的正则表达式,将匹配he这个单词
var re = /he/;
var str = "he";
var str2 = "ha";
alert(re.test(str));//true
alert(re.test(str));//false
我们可以在.html中的<script中进行测试,具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
//最简单的正则表达式,将匹配he这个单词
var re = /he/;
var str = "he";
var str2 = "ha";
alert(re.test(str));//true
alert(re.test(str2));//false
</script>
</body>
</html>
运行以上代码就可以看到弹框信息。请自行测试。之后的代码将不再提供.html文件。请自行复制相应代码到<script></script>中进行测试。
//最简单的正则表达式,将匹配he这个单词
var reg = /he/;
var str = "HE";
//匹配大写的HE将返回false;
console.log(reg+"--test--"+str+"="+reg.test(str));//false
/*
* 重新定义正则表达式让其支持大小写
* 在正则表达式中使用i的意思就是:忽略大小写。
*/
reg = /he/i;
str = "HE";
console.log(reg+"--test--"+str+"="+reg.test(str));//true
str = "Certainly!He loves her!";
//,只要包含he(HE)就符合,如果要只是he或HE,不能有其它字符,则可使用^和$
console.log(reg+"--test--"+str+"="+reg.test(str));//true
reg = /^he/i;// ^ 代表字符开始位置 ,就是必须是以 he 进行开头。
//false,因为he不在str最开始
console.log(reg+"--test--"+str+"="+reg.test(str));
str = "He is a good boy!";
//true,He是字符开始位置,很明显就是HE开头的,加上i不区分大小写。
console.log(reg+"--test--"+str+"="+reg.test(str));
//这时候我们需求又来了,我们希望必须以 he 结束,不能有其它的了,那么就要使用$符号了。
reg = /^he$/i;//$表示字符结束位置
//false, 很明显str = "He is a good boy!";不是以 he就是结束了。
console.log(reg+"--test--"+str+"="+reg.test(str));
str = "He";
//true;
console.log(reg+"--test--"+str+"="+reg.test(str));
//当然,这样不能发现正则表达式有多强大,因为我们完全可以在上面的例子中使用==或indexOf
reg = /\s/;// \s匹配任何空白字符,包括空格、制表符、换页符等等
str= "user Name";//用户名包含空格
//true
console.log(reg+"--test--"+str+"="+reg.test(str));
str= "userName";//用户名包含空格
//false
console.log(reg+"--test--"+str+"="+reg.test(str));
str = "user Name";//用户名包含制表符
//true
console.log(reg+"--test--"+str+"="+reg.test(str));
/*
* 我们解释下这个正则表达式的意思:
*
* 首先解读:[a-z] : []匹配指定范围内的任意字符,就是a,b,c,d
* /i :说明我们不区分大小写:A,a,B,c都是支持的。
* ^ : 这个是必须以什么开头,那么就是必须以英文字母开头,如果是以 1,2等数字或者别的字符开头就是不匹配的。
*
*/
reg=/^[a-z]/i;//[]匹配指定范围内的任意字符,这里将匹配英文字母,不区分大小写
str="variableName";//变量名必须以字母开头
//true
console.log(reg+"--test--"+str+"="+reg.test(str));
str="123abc";
//false;
console.log(reg+"--test--"+str+"="+reg.test(str));
中场休息下,写的实在是太累了,我们总结下:上面我们学习到了什么:
// : 使用//表示我们是一个正则表达式的写法;
i : 表示我们不区分大小写;
^ : 表示必须要以什么进行开头;
[] : 匹配指定范围内的任意字符;
$ : 表示以什么字符结尾。
(2)初露锋芒
初露锋芒之【手机号码】正则表达式
现在我们的需求是这样的,判断用户输入的手机号是否是正常的手机号码。我们期望是这样的:只有13、15、18开头的11位手机号码是合理的。
我们分析下,我们要满足几点:
1> 11位数字
2> 1开头
3> 第二位置是3,5,8
4> 剩下的几位是随意数字。
我们先看看1>,怎么确保输入的是11位数呢?我们会使用到{n}的表达式:
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
测试代码如下:
var reg = /o{2}/;
var str = "Bob";
//false
alert(reg.test(str));
var str = "food";
//true
alert(reg.test(str));
那么配置11位数字的正则表达式就是,我们容易写成如下表达式:
var reg = /[0-9]{11}/;
这个确实是能匹配到11位的数字,但是12位的数字也是能匹配的,10位的当然是无法匹配,所以正确的方式就是要限定开始+结尾,正确的写法就是:
var reg = /^[0-9]{11}$/;
这个表达式只能是11位数字了,测试代码如下:
var reg = /^[0-9]{11}$/;
var str = "110123443211";
//false
alert(reg.test(str));
var str = "1101234432";
//false
alert(reg.test(str));
var str = "11012344321";
alert(reg.test(str));//true
接下来我们来满足第二个条件,就是1开头,这个就比较简单了,改造之后的表达式为:
var reg = /^1[0-9]{10}$/;
或者
var reg = /^[1][0-9]{10}$/;
那么这两种方式有什么区别呢?第二种方式应该是比较好扩展,[]表示是匹配多个字符,那么我们如果期望是以1,2开始的话,那么我们这么写:
var reg = /^[12][0-9]{10}$/;
注意这里不是12,就是满足以1开头或者以2开头的数字而已。
另外这里的{}中的是10,因为我们原本是11位,1占用1位,所以11-1=10就是10位了。
紧接着我们来满足第二位是3,5,8数字,这个实现,其实我们在以上的时候就提到了,就是[12]的表示方式,3,5,8就是[358],那么我们的正则表达式就是:
var reg = /^[1][358][0-9]{9}$/;
ok,到底算是高一段落了,我们还是来总结下,使用的到表达符号:
// : 表示是一个正则表达式;
[]: 匹配指定范围内的任意字符;
{n} : 匹配确定的n次,若:a{2},那么可以匹配到12aa,不能匹配到12a或者12aaa;
^:以什么字母开始;
$: 以什么结束;
i:不区分小写;
这里最后提供一个.html代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
/**
* 是否是合理的手机号.
* @param {Object} input
*/
function isMobile(input){
var reg = /^[1][358][0-9]{9}$/;
return reg.test(input);
}
//用户输入的.
var input = "13012344321";
//true;
alert(isMobile(input));
//用户输入的.
var input = "12012344321";
//false;
alert(isMobile(input));
</script>
</body>
</html>
初露锋芒之【邮箱】正则表达式
现在我们的需求是这样的,判断用户输入的是否是合理的邮箱,那么邮箱的一个规则是什么呢?(当然我们这里是我们的假设,实际中请参考实际的需求或者直接在网上寻找邮箱的正则表达式)。
1> 以字母数字以及-开头、不限制位数
2> 紧接有一个@
3> 之后又是字母数字以及-多个以点结尾
4> 最后以字母数字2-4位结束。
在这里我们会学习到的表达式符号是:
[]: 匹配指定范围内的任意字符;
+:+号表示字符至少要出现1次
\:转义字符,由于-是特殊字符,所以我们需要使用\-进行转义。
(pattern):匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到;
For example:
reg = /^a|bc$/;//将匹配开始位置的a或结束位置的bc
str ="add";
alert(reg.test(str));//true
reg = /^(a|bc)$/;//将匹配a或bc
str ="bc";
alert(reg.test(str));//true
{m,n}: m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
接下来我们来实现以下:
1> 以字母数字以及-开头、不限制位数
满足这个条件的正则表达式是:
var reg = /^([a-zA-Z0-9\-])+/;
1> 紧接有一个@
var reg = /^([a-zA-Z0-9\-])+@/;
2> 之后又是字母数字以及-多个以点结尾
var reg = /^([a-zA-Z0-9\-])+@(([a-zA-Z0-9\-])+\.)+ /;
3> 最后以字母数字2-4位结束。
var reg = /^([a-zA-Z0-9\-])+@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
测试代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
/**
* 是否是合理的邮箱
* @param {Object} input
*/
function isEmail(input){
var reg = /^([a-zA-Z0-9\-])+@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return reg.test(input);
}
//用户输入的.
var input = "abc@qq.com";
//true;
alert(isEmail(input));
</script>
</body>
</html>
在这里我要告诉大家另外一个点,正则表达式针对于同一个要实现的问题并不是固定的,就拿手机号码来说,有其它不同的写法能满足我们要的结果。
(3)过关斩将
我们自己按照我们自己的要求写完了一两个正则表达式例子,实际中我们并不需要完全会自己写,现在有很多的在线生成工具:http://tool.lu/regex/ 我们只需要解读就好了。
那么来解读下别人写的手机号码的校验吧,打开网址,你会看到手机号码的正则表达式如下:
var reg = /(13\d|14[57]|15[^4,\D]|17[678]|18\d)\d{8}|170[059]\d{7}/
这里有新的知识我们要学习:
\d: 匹配一个数字字符。等价于 [0-9]。
\D : 匹配一个非数字字符。等价于 [^0-9],所以在某些场合^还有非的意思。
[^a-z]:负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。
我们根据 | 拆分我们正则表达式为:
(13\d|14[57]|15[^4,\D]|17[678]|18\d)\d{8}
这部分表示:
(13[0-9]|14[57]|15[^4,[^0-9]]|17[678]|18[0-9])[0-9]{8}
也就是说:
13[0-9] : 131,132,133等
14[57] : 145 , 147
15[^4,[^0-9]]:这个很深奥,需要好好解读下,首先我们先说下不能匹配到的是154,那么怎么正确解读呢?首先是15开始这个没什么疑问, ^4意思不能出现4,^,不能有,然后就是
^[^0-9],然后这个就是等待与[0-9]了,说白了除了4的其它数字都能满足。
剩下的就没什么难度,自己解读下就好了。
这里已经是3位了,剩下的\d{8}就是任意的8位数字。
170[059]\d{7}
| 之后的代码就比较简单了,就是如果是170的话,只能是
1700… ,1705… 1709….其它的就不符合。
好了解读完了,所以要把js完全学透传还是有一定难度的。
参考:
精通 JS正则表达式
http://www.cnblogs.com/aaronjs/archive/2012/06/30/2570970.html
JS中正则表达式概述
http://www.cnblogs.com/yangmingming/archive/2010/03/10/1682470.html
正则表达式全部符号解释
http://www.cnblogs.com/yirlin/archive/2006/04/12/373222.html
【Spring Boot 系列博客】
58. Spring Boot国际化(i18n)【从零开始学Spring Boot】
57. Spring 自定义properties升级篇【从零开始学Spring Boot】
56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】
55. spring boot 服务配置和部署【从零开始学Spring Boot】
54. spring boot日志升级篇—logback【从零开始学Spring Boot】
52. spring boot日志升级篇—log4j多环境不同日志级别的控制【从零开始学Spring Boot】
51. spring boot属性文件之多环境配置【从零开始学Spring Boot】
50. Spring Boot日志升级篇—log4j【从零开始学Spring Boot】
49. spring boot日志升级篇—理论【从零开始学Spring Boot】
48. spring boot单元测试restfull API【从零开始学Spring Boot】
47. Spring Boot发送邮件【从零开始学Spring Boot】
46. Spring Boot中使用AOP统一处理Web请求日志
45. Spring Boot MyBatis连接Mysql数据库【从零开始学Spring Boot】
44. Spring Boot日志记录SLF4J【从零开始学Spring Boot】
43. Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
42. Spring Boot多数据源【从零开始学Spring Boot】
41. Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】
40. springboot + devtools(热部署)【从零开始学Spring Boot】
39.4 Spring Boot Shiro权限管理【从零开始学Spring Boot】
39.3 Spring Boot Shiro权限管理【从零开始学Spring Boot】
39.2. Spring Boot Shiro权限管理【从零开始学Spring Boot】
39.1 Spring Boot Shiro权限管理【从零开始学Spring Boot】
38 Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】
37 Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】
36 Spring Boot Cache理论篇【从零开始学Spring Boot】
35 Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
34Spring Boot的启动器Starter详解【从零开始学Spring Boot】
33 Spring Boot 监控和管理生产环境【从零开始学Spring Boot】
32 Spring Boot使用@SpringBootApplication注解【从零开始学Spring Boot】
31 Spring Boot导入XML配置【从零开始学Spring Boot】
更多查看博客: http://412887952-qq-com.iteye.com/