1.概述

正则表达式(实例)是一种表达文本模式(即字符串结构)的方法。

创建方式有两种方式:

一种是使用字面量,以斜杠表示开始和结束。


var regex = /xyz/

另一种是使用RegExp构造函数。


var regex = new RegExp('xyz');

它们的主要区别是,第一种方法在引擎编译代码时,就会新建正则表达式,第二种方法在运行时新建正则表达式,所以前者的效率较高。而且,前者比较便利和直观,所以实际应用中,基本上都采用字面量定义正则表达式。

2.实例属性

  1. i:忽略大小写
  2. m:多行模式
  3. g:全局搜索

3.实例方法

3.1 RegExp.prototype.test()

正则实例对象的test方法返回一个布尔值,表示当前模式是否能匹配参数字符串。


/小智/.test('小智 终身学习执行者') // true

reg.exec(str) 返回匹配结果数组,不匹配则返回null,每执行一次exec就向后匹配一次

3.2 RegExp.prototype.exec()

3.2.1 reg.exec(str) 返回匹配结果数组,不匹配则返回null,每执行一次exec就向后匹配一次


var s = '_x_x';
var r1 = /x/;
var r2 = /y/; r1.exec(s) // ["x"]
r2.exec(s) // null

3.2.1.2如果表达式里有括号(),称为组匹配,返回结果中,第一个是整体匹配结果,后面依次是每个括号匹配的结果


var s = '_x_x';
var r = /_(x)/; r.exec(s) // ["_x", "x"]

exec方法的返回数组还包含以下两个属性:

  1. input:整个原字符串。
  2. index:整个模式匹配成功的开始位置(从0开始计数)。

var r = /a(b+)a/;
var arr = r.exec('_abbba_aba_'); arr // ["abbba", "bbb"] arr.index // 1
arr.input // "_abbba_aba_"

3.2.3 如果表达式中有g选项进行全局搜索,则可以多次使用 exec,下次的匹配从上次的结果后开始


var reg = /a/g;
var str = 'abc_abc_abc' var r1 = reg.exec(str);
r1 // ["a"]
r1.index // 0
reg.lastIndex // 1 var r2 = reg.exec(str);
r2 // ["a"]
r2.index // 4
reg.lastIndex // 5 var r3 = reg.exec(str);
r3 // ["a"]
r3.index // 8
reg.lastIndex // 9 var r4 = reg.exec(str);
r4 // null
reg.lastIndex // 0

4.字符串的实例方法

4.1 str.match(reg),与 reg.exec相似,但是,如果使用g选项,则str.match一次性返回所有结果。


var s = 'abba';
var r = /a/g; s.match(r) // ["a", "a"]
r.exec(s) // ["a"]

4.2 str.search(reg) ,返回匹配成功的第一个位置,如果没有任何匹配,则返回-1。


'_x_x'.search(/x/)
// 1

4.3 str.replace(reg,newstr) ;

用第一个参数reg去匹配,用第二个参数newstr 去替换,正则表达式如果不加g修饰符,就替换第一个匹配成功的值,否则替换所有匹配成功的值。


'aaa'.replace('a', 'b') // "baa"
'aaa'.replace(/a/, 'b') // "baa"
'aaa'.replace(/a/g, 'b') // "bbb"

4.4 str.split(reg[,maxLength]) 用匹配的模式切割,第二个参数是限制返回结果的最大数量

5. 匹配规则

5.1 字面量字符和元字符

大部分字符在正则表达式中,就是字面的含义,比如/a/匹配a,/b/匹配b。如果在正则表达式之中,某个字符只表示它字面的含义(就像前面的a和b),那么它们就叫做“字面量字符”(literal characters)。
除了字面量字符以外,还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters),主要有以下几个。

(1) 点字符(.)
点字符(.)匹配除回车(r)、换行(n) 、行分隔符(u2028)和段分隔符(u2029)以外的所有字符。


/c.t/

上面代码中,c.t匹配c和t之间包含任意一个字符的情况,只要这三个字符在同一行,比如cat、c2t、c-t等等,但是不匹配coot

(2)位置字符

  • ^ 表示字符串的开始位置
  • $ 表示字符串的结束位置

// test必须出现在开始位置
/^test/.test('test123') // true // test必须出现在结束位置
/test$/.test('new test') // true // 从开始位置到结束位置只有test
/^test$/.test('test') // true
/^test$/.test('test test') // false

(3)选择符(|)

竖线符号(|)在正则表达式中表示“或关系”(OR),即cat|dog表示匹配cat或dog。


/11|22/.test('911') // true

上面代码中,正则表达式指定必须匹配11或22。

5.2 转义符

正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+,就要写成+。


/1+1/.test('1+1')
// false /1\+1/.test('1+1')
// true

正则表达式中,需要反斜杠转义的,一共有12个字符:^、.、[、$、(、)、|、*、+、?、{和。需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。


(new RegExp('1\+1')).test('1+1')
// false (new RegExp('1\\+1')).test('1+1')
// true

5.3 字符类

字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如[xyz] 表示x、y、z之中任选一个匹配。


/[abc]/.test('hello world') // false
/[abc]/.test('apple') // true

有两个字符在字符类中有特殊含义。

(1)脱字符(^)
如果方括号内的第一个字符是[^xyz]表示除了x、y、z之外都可以匹配:


/[^abc]/.test('hello world') // true
/[^abc]/.test('bbc') // false

如果方括号内没有其他字符,即只有[^],就表示匹配一切字符,其中包括换行符。相比之下,点号作为元字符(.)是不包括换行符的。


var s = 'Please yes\nmake my day!'; s.match(/yes.*day/) // null
s.match(/yes[^]*day/) // [ 'yes\nmake my day']

上面代码中,字符串s含有一个换行符,点号不包括换行符,所以第一个正则表达式匹配失败;第二个正则表达式[^]包含一切字符,所以匹配成功。

(2)连字符(-)

某些情况下,对于连续序列的字符,连字符(-)用来提供简写形式,表示字符的连续范围。比如,[abc]可以写成[a-c],[0123456789]可以写成[0-9],同理[A-Z]表示26个大写字母。


/a-z/.test('b') // false
/[a-z]/.test('b') // true

以下都是合法的字符类简写形式。


[0-9.,]
[0-9a-fA-F]
[a-zA-Z0-9-]
[1-31]

上面代码中最后一个字符类[1-31],不代表1到31,只代表1到3。

另外,不要过分使用连字符,设定一个很大的范围,否则很可能选中意料之外的字符。最典型的例子就是[A-z],表面上它是选中从大写的A到小写的z之间52个字母,但是由于在 ASCII 编码之中,大写字母与小写字母之间还有其他字符,结果就会出现意料之外的结果。


/[A-z]/.test('\\') // true

上面代码中,由于反斜杠('')的ASCII码在大写字母与小写字母之间,结果会被选中。

5.4 预定义模式

预定义模式指的是某些常见模式的简写方式。

  • d 匹配0-9之间的任一数字,相当于[0-9]
  • D 匹配所有0-9以外的字符,相当于[^0-9]
  • w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
  • W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
  • s 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]
  • S 匹配非空格的字符,相当于[^ \t\r\n\v\f]
  • b 匹配词的边界。
  • B 匹配非词边界,即在词的内部。

// \s 的例子
/\s\w*/.exec('hello world') // [" world"] // \b 的例子
/\bworld/.test('hello world') // true
/\bworld/.test('hello-world') // true
/\bworld/.test('helloworld') // false // \B 的例子
/\Bworld/.test('hello-world') // false
/\Bworld/.test('helloworld') // true

通常,正则表达式遇到换行符(n)就会停止匹配。


var html = "<b>Hello</b>\n<i>world!</i>"; /.*/.exec(html)[0]
// "<b>Hello</b>"

上面代码中,字符串html包含一个换行符,结果点字符(.)不匹配换行符,导致匹配结果可能不符合原意。这时使用s字符类,就能包括换行符。


var html = "<b>Hello</b>\n<i>world!</i>"; /[\S\s]*/.exec(html)[0]
// "<b>Hello</b>\n<i>world!</i>"

上面代码中,[Ss]指代一切字符。

5.5 重复类

模式的精确匹配次数,使用大括号({})表示。{n}表示恰好重复n次,{n,}表示至少重复n次,{n,m}表示重复不少于n次,不多于m次。


/lo{2}k/.test('look') // true
/lo{2,5}k/.test('looook') // true

上面代码中,第一个模式指定o连续出现2次,第二个模式指定o连续出现2次到5次之间。

5.6 量词符

*. ? 问号表示某个模式出现0次或1次,等同于{0, 1}
*. * 星号表示某个模式出现0次或多次,等同于{0,}
*. + 加号表示某个模式出现1次或多次,等同于{1,}

5.7 贪婪模式

上一小节的三个量词符,默认情况下都是最大可能匹配,即匹配直到下一个字符不满足匹配规则为止。这被称为贪婪模式。


var s = 'aaa';
s.match(/a+/) // ["aaa"]

上面代码中,模式是/a+/,表示匹配1个a或多个a,那么到底会匹配几个a呢?因为默认是贪婪模式,会一直匹配到字符a不出现为止,所以匹配结果是3个a。

如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。


var s = 'aaa';
s.match(/a+?/) // ["a"]

除了非贪婪模式的加号,还有非贪婪模式的星号(*)和非贪婪模式的问号(?)

  • +?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。
  • *?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。
  • ??:表格某个模式出现0次或1次,匹配时采用非贪婪模式。

5.8 组匹配

(1)概述
正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。


/fred+/.test('fredd') // true
/(fred)+/.test('fredfred') // true

上面代码中,第一个模式没有括号,结果+只表示重复字母d,第二个模式有括号,结果+就表示匹配fred这个词。

下面是另外一个分组捕获的例子。


var m = 'abcabc'.match(/(.)b(.)/);
m
// ['abc', 'a', 'c']

上面代码中,正则表达式/(.)b(.)/一共使用两个括号,第一个括号捕获a,第二个括号捕获c。

注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。


var m = 'abcabc'.match(/(.)b(.)/g);
m // ['abc', 'abc']

正则表达式内部,还可以用n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号。


/(.)b(.)\1b\2/.test("abcabc")
// true

上面的代码中,1表示第一个括号匹配的内容(即a),2表示第二个括号匹配的内容(即c)。

(2)非捕获组
(?:x)称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。

非捕获组的作用请考虑这样一个场景,假定需要匹配foo或者foofoo,正则表达式就应该写成/(foo){1, 2}/,但是这样会占用一个组匹配。这时,就可以使用非捕获组,将正则表达式改为/(?:foo){1, 2}/,它的作用与前一个正则是一样的,但是不会单独输出括号内部的内容。


var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]

上面代码中的模式,一共使用了两个括号。其中第一个括号是非捕获组,所以最后返回的结果中没有第一个括号,只有第二个括号匹配的内容。

(3)先行断言

x(?=y)称为先行断言(Positive look-ahead),x只有在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟着百分号的数字,可以写成/d+(?=%)/。

“先行断言”中,括号里的部分是不会返回的。


var m = 'abc'.match(/b(?=c)/);
m // ["b"]

上面的代码使用了先行断言,b在c前面所以被匹配,但是括号对应的c不会被返回。

(4)先行否定断言
x(?!y)称为先行否定断言(Negative look-ahead),x只有不在y前面才匹配,y不会被计入返回结果。比如,要匹配后面跟的不是百分号的数字,就要写成/d+(?!%)/。


/\d+(?!\.)/.exec('3.14')
// ["14"]

上面代码中,正则表达式指定,只有不在小数点前面的数字才会被匹配,因此返回的结果就是14。

6. 实战

6.1 消除字符串首尾两端的空格


var str = ' #id div.class ';
str.replace(/^\s+|\s+$/g, '')
// "#id div.class"

6.2 验证手机号码


var reg = /1[24578]\d{9}/; reg.test('154554568997'); //true
reg.test('234554568997'); //false

6.3 把手机号码替换成 *


var reg = /1[24578]\d{9}/; var str = '姓名:张三 手机:18210999999 性别:男'; str.replace(reg, '***') //"姓名:张三 手机:*** 性别:男"

6.4 匹配网页标签


var strHtlm = '小智小智<div>222222@.qq.com</div>小智小智'; var reg = /<(.+)>.+<\/\1>/; strHtlm.match(reg); // ["<div>222222@.qq.com</div>"]

6.6 千位分隔符


let str = '100002003232322'; let r = str.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); console.log(r); //100,002,003,232,322

参考链接

https://developer.mozilla.org...

https://wangdoc.com/javascrip...

一个笨笨的码农,我的世界只能终身学习!

JavaScript(E5,6) 正则学习总结学习,可看可不看!的更多相关文章

  1. javascript权威指南第6版学习笔记

    javascript权威指南第6版学习笔记 javascript数组.函数是特殊对象 看一点少一点. 3.1.4 hello.js内容是 var x=.3-.2;var y=.2-.1 console ...

  2. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...

  3. 2、JavaScript 基础二 (从零学习JavaScript)

     11.强制转换 强制转换主要指使用Number.String和Boolean三个构造函数,手动将各种类型的值,转换成数字.字符串或者布尔值. 1>Number强制转换 参数为原始类型值的转换规 ...

  4. 1、JavaScript 基础一 (从零学习JavaScript)

    1:定义:javascript是一种弱类型.动态类型.解释型的脚本语言. 弱类型:类型检查不严格,偏向于容忍隐式类型转换. 强类型:类型检查严格,偏向于不容忍隐式类型转换. 动态类型:运行的时候执行类 ...

  5. Html JavaScript网页制作与开发完全学习手册

    Html JavaScript网页制作与开发完全学习手册 篇 HTML技术章 HTML入门 1.1 什么是HTML 1.1.1 HTML的特点 1.1.2 HTML的历史 1.2 HTML文件的基本结 ...

  6. 小白学习VUE第一篇文章---如何看懂网上搜索到的VUE代码或文章---使用VUE的三种模式:

    小白学习VUE第一篇文章---如何看懂网上搜索到的VUE代码或文章---使用VUE的三种模式: 直接引用VUE; 将vue.js下载到本地后本目录下使用; 安装Node环境下使用; ant-desig ...

  7. 前端学习:学习笔记(HTML部分)

    前端学习:学习笔记(HTML部分) HTML学习总结(图解) HTML简介 1.HTML是什么? 超文本标记语言 超文本:文字/图片/音频/视频.... 标记/标签 2.HTML的用途? 是用来编写静 ...

  8. duilib学习 --- 360demo 学习

    我想通过360demo的学习,大概就能把握duilib的一般用法,同时引申出一些普遍问题,和普遍解决方法.并在此分享一些链接和更多内容的深入学习..... 原谅我是一个菜鸟,什么都想知道得清清楚楚.. ...

  9. “假学习“&”真学习“?(摘)

    什么叫做“假学习”? 一.看书 买一堆书,有空看看.看书,这是典型的假学习.看书看不懂还在看,就是假学习,欺骗自己,安慰自己正在学习而已.专业书都写得很好,但大都是写给已经懂的人看的.看书的最大作用就 ...

随机推荐

  1. 011 Container With Most Water 盛最多水的容器

    给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) .画 n 条垂直线,使得垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线,使得它们 ...

  2. (转)Linux系统stat指令用法

    <Linux系统stat指令用法>  原文:https://www.cnblogs.com/linux-super-meng/p/3812695.html stat指令:文件/文件系统的详 ...

  3. 记一次内存溢出java.lang.OutOfMemoryError: unable to create new native thread

    一.问题: 春节将至,系统访问量进入高峰期.随之系统出现了异常:java.lang.OutOfMemoryError: unable to create new native thread.在解决这个 ...

  4. Spark Mllib里的如何对两组数据用皮尔逊计算相关系数

    不多说,直接上干货! import org.apache.spark.mllib.stat.Statistics 具体,见 Spark Mllib机器学习实战的第4章 Mllib基本数据类型和Mlli ...

  5. pat1079. Total Sales of Supply Chain (25)

    1079. Total Sales of Supply Chain (25) 时间限制 250 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHE ...

  6. Unity GL 画圆

    Unity下GL没有画圆的函数,只能自己来了. 如果能帮到大家,我也很高兴. 虽然没有画圆的函数,但是能画直线,利用这一点,配合微积分什么的,就可以画出来了.反正就是花很多连在一起的直线,每条直线足够 ...

  7. DockerSwarm 微服务部署

    一.简介 之前<服务Docker化>中,使用 docker-compose.yml 来一次配置启动多个容器,在 Swarm 集群中也可以使用 compose 文件 (docker-comp ...

  8. Fiddler 抓包工具总结(转)

    Fiddler 抓包工具总结   阅读目录 1. Fiddler 抓包简介 1). 字段说明 2). Statistics 请求的性能数据分析 3). Inspectors 查看数据内容 4). Au ...

  9. Keymob带你玩转新广告法下的移动营销

    2015年9月1日新广告法正式实施,对广告代言人.广告类别.广告语等都做了一系列新规定,堪称有史以来最严广告法.随着新广告法的实施,以往一些庸俗.夸张的广告也逐渐和大众说再见了. 2015年 “互联网 ...

  10. 报错:Program "sh" not found in PATH

    参考原文:http://vin-mail.blog.163.com/blog/static/37895280201211932919513/ 如果你按照我的方法 先配置了cygwin的环境变量,在打开 ...