正则表达式(Regular Expression)是计算机科学的一个概念。 正则表达式使用单个字符窜来描述、匹配一系列符合某个句法规则的字符窜。 在很多文本编辑器里, 正则表达式通常用来被检索替换哪些符合某个模式的文本。

正则表达式实例

创建

JavaScript通过内置对象 RegExp支持正则表达式, 有两种方式创建正则表达式对象, 如果我们想匹配字符窜中<%xxx%>两个百分号分割的字符窜可以这么写。

  • 构造函数

var regExp = new RegExp('&lt;%[^%&gt;]+%', 'g');
  • 字面量

var regExp = /&lt;%[^%&gt;]%&gt;/g;

最后的g代表全局, 还有几个修饰符

RegExp实例对象有五个属性

  1. g: global, 全文搜索,不添加的话搜索到第一个结果停止搜索。
  2. i: ignore case, 忽略大小写,默认大小写敏感。
  3. m: multiple lines, 多行搜索。
  4. lastIndex: 是当前表达式模式首次匹配内容中最后一个字符的下一个位置,每次正则表达式匹配成功匹配时, lastIndex属性值都会随之改变。
  5. sourse:正则表达式的文本字符窜。

除了正则表达式编译为内部格式从而使执行更快的compile()方法, 对象还有两个我们常用的方法。

元字符

正则表达式让人望而却步的一个重要原因就是转译字符太多, 组合非常多, 但是正则表达式的元字符(在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符)并不多



() [] {} \ ^ $ | ? * + .

并不是每个元字符都有特定的意义,在不同的组合中元字符有不同的意义, 分类看一下

  • t 水平制表符 tab
  • r 回车符 carriage return
  • n 换行符 newline
  • f page feed 换页符
  • cX 与X对应的控制字符(Ctrl + X )
  • v 垂直制表符
  • 0 空字符

字符类

一般情况下正则表达式一个字符(转译字符算一个) 对应字符窜一个字符,表达式 abt 的含义


ab水平制表符

但是我们可以使用元字符[]来构建一个简单的类, 所谓类是指,符合某些特征的对象, 是一个泛指,而不是特指某个字符了, 我们可以使用表达式[abc], 把字符a或b或c归为一类,表达式可以匹配这类的字符。

字符类取反

元字符[]组合可以创建一个类,我们还可以使用元字符^创建反向类/负向类,反向类的意思是不属于XXX类的内容, 表达式1表示不是字符a或b或c的内容。

范围类

按照上面的说明如果希望匹配单个数字那么表达式是这样的


[0123456789]

如果是字母那么。。。 好麻烦, 正则表达式还提供了范围类,我们可以使用x-y来连接两个字符表示从x到y的任意字符, 这是个闭区间, 也就是说包含x和y本身, 这样匹配小写字母就很简单了。


[a-z]

预定义类

刚才使用正则我们创建了几个类,来表示数字,字母等,但这样写很麻烦,正则表达式为我们了几个常用的预定义类来匹配常见的字符。

字符 等价类 含义
. [^rt] 除了回车符和换行符之外的所有字符
d [0-9] 数字字符
D [^0-9] 数字字符
s [\t\n\x0B\f\r] 空白符
S [^t\n\x0B\f\r] 非空白符
w [a-zA-Z_0-9] 字母,数字,下划线
W [^a-zA-Z_0-9] 非字母,数字,下划线

有了这些预定义类, 写一些正则就很方便了, 比如我们希望匹配一个 ab + 数字 + 任意字符的字符窜, 就可以写了abd.

可以把正则表达式,想象成一种模式,字符窜匹配正则表达式定义的模式的结果


string.match(regExpPattern)

边界

正则表达式还提供了几个常用的边界匹配字符。

字符 含义
^ 以xxx开头, ^ 开头的匹配参照对象是整个字符窜
$ 以xxx结尾, $ 结尾的匹配参照对象也是整个字符窜
b 单词边界, '-'也是单词边界!
B 非单词边界

^ 开头的匹配参照对象是整个字符窜,
$ 结尾的匹配参照对象也是整个字符窜,
限制的是整个字符窜。 var regExpPattern = /^h\dm/g;
'h2m h3m h2m'.match(regExpPattern); // h2m, 记住这是以整个字符窜去匹配的 //同理 var regExpExpPattern = /h\dm$/g;
'h2m h3m h3m'.match(regExpPattern); // h3m //使用场景 手机号匹配 '13423454234'.match(/^1\d{10}$/g)

量词

之前,介绍的方法都是一一匹配,如果希望匹配一个连续20次数字的字符窜难道我们需要写成这样?


\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d..

为此正则表达式引入了一些量词

字符 含义
? 出现零次或一次(最多出现一次)
+ 出现一次或多次(至少出现一次)
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n到m次
{n,} 至少出现n次
{,m} 最多出现m次

var regExp = /w+\bBryon/ regExp.test('hi Bryon'); // true regExp.test('Welcome Byron'); // true regExp.test('Byron'); //false //匹配带有3到1个小数的数字
var reg = /\d+\.d{1,3}

贪婪模式与非贪婪模式

看了量词的介绍,也许爱思考的同学会想到关于匹配原则的一些问题, 比如{3,5} 这个量词, 要是在句子中出现了十次, 那么他是每次匹配三个还是五个,反正3,4,5都满足3~5的条件。

量词在默认下是尽可能多的匹配的,也就是大家常说的贪婪模式。


// ['12345','6789'];
'12345679'.match(/\d{3,5}/g);

既然有贪婪模式,那么肯定会有非贪婪模式,让正则表达式尽可能少的匹配,u额就是说一旦成功匹配不再继续尝试,做法很简单, 在量词后加上?即可


//['123','456','789'] '123456789'.match(/\d{3,5}?/g);

分组

有时候希望使用量词的时候匹配多个字符,而不是像上面例子只是匹配一个,比如希望匹配Byron出现20次的字符窜,写成Byron{20}的话匹配的是Byro+n出现20次。


//写成Byron{20}的话匹配的是Byro+n出现20次。
/Byron{20}/g

怎么把Byron作为一个整体呢? 使用()就可以达到此目的,在正则中成为分组。


//分组在regExp.exec(stringObj)中会单独显示在返回结果中。 (Byron){20}

或 |

如果希望匹配Byron或Casper出现20次该怎么办呢? 可以使用字符| 达到或的功效


(Byron|Casper){20}

使用分组的正则表达式会把匹配项也放到分组中,默认是按数字编号分发的,可以根据编号获得捕获的分组内容,这在一些希望具体操作第几个匹配项的函数中很有用。


// Group 1 : Byron , Group 2: ok
(Byron).(ok)

分组嵌套

如果有分组嵌套的情况,外面的组的编号靠前


// group 1: (^|%&gt;)[^\t]*, Group 2: (^|%&gt;)
((^|%&gt;)[^\t]*)

忽略分组

有时候我们不希望捕获某些分组,只需要在分组内加上?: 就可以了, 这并不意味着该分组内容不属于正则表达式,只是不会给这个分组加编号而已。


(?:Bryon).(ok)

前瞻

表达式 含义
exp1(?=exp2) 匹配后面是exp2的exp1
exp1(?!exp2) 匹配后面不是exp2的exp1

var regExp = /good(?=Byron)/; regExp.exec('goodByron123'); // ['good']
regExp.exec('goodCapser123'); // null

通过上面例子可以看出exp1(?=exp2)表达式, 但只有其后面内容是exp2的时候才会匹配,也就是两个条件,exp1(?!exp2)比较类似。

正则表达式相关的方法

  • RegExp.prototype.test(str)

该方法用于测试字符窜参数中是否匹配正则表达式模式,如果存在则返回true,否则返回false。


var reg = /\d+\.\d{1,2}$/g; reg.test('123.45'); // true
reg.test('0.2'); // true reg.test('a.34'); //false
reg.test('34.5678'); //false

//判断手机号是否正确
function isPhoneNum(phoneNum) {
var phoneNumberTester = /^1\d{10}$/;
return phoneNumberTester.test(phoneNum);
}
  • RegExp.prototype.exec(str)

该方法用于正则表达式模式在字符窜中运行查找,如果exec()找到匹配的文本,则返回一个结果,否则返回null

除了数组元素和length属性之外, exec()方法返回对象还包括两个属性。

  1. index属性声明的是匹配文本的第一个字符的位置。
  2. input属性则存放的是被检索的字符窜string。

非全局调用

调用非全局的RegExp对象的exec()时,返回数组的第一个元素是与正则表达式相匹配的文本,第二个元素是与RegExpObject的第一个子表达式相匹配的文本(如果有的话), 第三个元素时与RegExp对象的第二个子表达式相匹配的文本(如果有的话),以此类推。

全局调用

调用全局的RegExp对象的exec()时,它会在RegExp实例的lastIndex属性指定的字符处开始检索字符窜string

  1. 当exec()找到了与表达式相匹配的文本时, 在匹配后, 它将把RegExp实例的lastIndex属性设置为匹配文本的最后一个字符的下一个位置。可以通过反复调用exec()方法来遍历字符窜中的所有哦匹配文本。
  2. 当exec()再也找不到匹配的文本时,它将返回null,并把lastIndex属重置为0。

var reg = /\d/g; var r = reg.exec('a1b2c3'); console.log(r); console.log(reg.lastIndex); // 2 r = reg.exec('a1b2c3'); console.log(reg.lastIndex); // 4

var reg = /\d/g; while (r = reg.exec('a1b2c3')) {
console.log(r.index + ':' + r[0])
} //1:1 , 3:2, 5:3
  • String.prototype.search(reg)

search()方法用于检索字符窜中指定的子字符串,或检索与正则表达式相匹配的子字符窜。

search()方法不执行全局匹配,它将忽略标志g, 它同时忽略正则表达式对象的lastIndex属性,并且总是从字符窜的开始进行检索,这意味着它总是返回字符窜的第一个匹配的位置。

  • String.prototype.match(reg)

match()方法将检索字符窜,以找到一个或多个与regexp匹配的文本。但regexp是否具有标志g对结果影响很大。

非全局调用

如果regexp没有标志g,那么match()方法就只能在字符窜中执行一次匹配。如果没有找到任何匹配的文本,match()将返回null。否则它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。

该数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。

  1. index属性声明的是匹配文本的起始字符在字符窜中的位置。
  2. input属性声明的是对stringObject的引用。
  • String.prototype.replace(reg, replaceStr|| function callback())

关于string对象的replace方法, 我们最常用的是传入两个字符窜的做法,但这种做法有个缺陷,只能replace一次。



'abcabcabc'.replacce('bc', 'X') //aXabcabc

replace方法的第一个参数还可以传入RegExp对象,传入正则表达式可以使replace方法更加强大灵活


'abcabcabc'.replace(/bc/g, 'X'); //aXaXaX
'abcabcabc'.replace(bc/gi, 'X'); // aXaXaX

如果replace方法的第一个参数传入的是带分组的正则表达式,我们在第二个参数中可以使用$1...$9来获取相应分组内容, 比如希望把字符窜1<%2%>34>%567%>89的<%x%>换为&dollar;#x#$, 我们可以这样

'1<%2%>34>%567%>89的<%x%>'.replace(/<%(d+)%>)/g, '@#$1#@');
// 1@#2#@34@#567#@89

当然还有很多方式可以达到这一目的,这里只是演示一下利用分组内容,我们在第二个参数中使用@#&dollar;1#@, 其中$1表示被捕获的分组内容弄, 在一些js模板函数中可以经常见到这种方式替换字符窜。

可以通过修改replace方法的第二个参数,使replace更加强大,在前面的介绍中,只能把所有匹配替换为固定内容,但如果我希望把一个字符窜中所有数字,都用小括号包起来该怎么弄?


'2398sdadads1smdsa3mmm23mmmbb'.replace(/\d+/g, function(matchedStr, groupContent$, index, strObj ) {
return '(' + matchedStr + ')';
})

把replace方法的第二个参数传入一个function,这个function会在每次匹配替换的时候调用,算是个每次替换的回调函数,我们使用了回调函数的第一个参数,也就是匹配内容,其实回调函数一共有四个参数。

  • 第一个参数很简单,是匹配字符窜。
  • 第二个参数是正则表达式分组内容,没有分组则没有该参数。
  • 第三个参数是匹配项在字符窜中的index。
  • 第四个参数则是原字符窜。

例子


'2398rsjdhahd2131kksdajdj23'.replace(/\d+/g, function(matchedSubStr,index, strObj) {
console.log(matchedSubStr + '\t' + index + '\t' + strObj);
return '(' + matchedSubStr +')';
}) //2398 0 2398rsjdhahd2131kksdajdj23
//2131 12 2398rsjdhahd2131kksdajdj23
//23 24 2398rsjdhahd2131kksdajdj23

这是没有分组的情况,打印出来的分别是匹配内容、匹配项index和原字符窜,看个有分组的。


'&lt;%1%&gt;&lt;%2%&gt;&lt;%3%&gt;'.replace(/&lt;%([^%&gt;]+)%&gt;/g, function(matchedStr, group, index, thisStrObj) {
console.log(matchedStr + '\t' + group + '\t' + index + '\t' + thisStrObj);
return group;
}) //&lt;%1%&gt; 1 0 &lt;%1%&gt;&lt;%2%&gt;&lt;%3%&gt;
//&lt;%2%&gt; 2 5 &lt;%1%&gt;&lt;%2%&gt;&lt;%3%&gt;
//&lt;%3%&gt; 3 10 &lt;%1%&gt;&lt;%2%&gt;&lt;%3%&gt;
//"123"
  • String.prototype.split(reg)

使用split方法把字符窜分割为字符数组


'a,b,c,d'.split(',');
// ['a','b','c','d']

和replace方法类似,在一些复杂的分割情况下我们可以使用正则表达式解决


'a1b2c3d'.split(/\d/); // ['a','b','c','d']

  1. abc

原文地址:https://segmentfault.com/a/1190000016599340

正则表达式-基础知识Review的更多相关文章

  1. javascript之正则表达式基础知识小结

    javascript之正则表达式基础知识小结,对于学习正则表达式的朋友是个不错的基础入门资料.   元字符 ^ $ . * + ? = ! : | \ / ( ) [ ] { } 在使用这些符号时需要 ...

  2. Scala学习笔记--正则表达式基础知识、如何在scala内使用

    正则表达式语法:https://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx 基础知识:正则表达式30分钟入门教程 http://www. ...

  3. java正则表达式基础知识(转)

    1基础 2.1 简单字符类 构造 描述 [abc] a,b或c [^abc] 除a,b或c外的字符 [a-zA-Z] a至z 或 A至Z [a-d[m-p]] a至d 或 m至p [a-z&& ...

  4. javascript 正则表达式基础知识汇总

    正则表达式:对字符串中的信息实现查找.替换和提取操作.(不支持注释和空白,必须写在一行内)正则表达式的创建:包含在一对斜杠之间的字符(直接量语法)例如:var pattern = /s$/;     ...

  5. C++11 正则表达式——基础知识介绍

    C++11开始支持正则表达式,使得处理文本更加简洁方便.C++11 支持六种正则表达式语法:ECMAScript, basic(POSIX Basic Regular Expressions), ex ...

  6. JavaScript正则表达式基础知识汇总

    一.创建正则对象: 1.构造函数RegExp创建正则对象 var pattern = new RegExp('s$'); //pattern匹配以s结尾的字符串 2.使用正则直接量 var patte ...

  7. Java正则表达式基础知识整理

    指定为字符串的正则表达式必须首先被编译为此类的实例.然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配.执行匹配所涉及的所有状态都驻留在匹配器中,所以多个 ...

  8. Java正则表达式基础知识及实例说明

    众所周知,在程序开发中,难免会遇到需要匹配.查找.替换.判断字符串的情况发生,而这些情况有时又比较复杂,如果用纯编码方式解决,往往会浪费程序员的时间及精力.因此,学习及使用正则表达式,便成了解决这一矛 ...

  9. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

随机推荐

  1. java——模拟新浪微博用户注册

    1.创建用户类,重写HashCode()和equals()方法: import java.util.*; public class User{ private String name; private ...

  2. Hadoop实战:微博数据分析

    项目需求 自定义输入格式,将明星微博数据排序后按粉丝数 关注数 微博数 分别输出到不同文件中. 数据集 下面是部分数据,猛戳此链接下载完整数据集 数据格式: 明星   明星微博名称    粉丝数    ...

  3. varnish pipe 和pass的区别分析

    这两天在学习varnish,在学到vcl时,不理解pipe和pass的区别以及如何区分加以应用.通过两天的搜索,总算是理清了概念.现在记录在博客上跟大家分享. 当 vcl_recv 函数接收到请求时, ...

  4. Comparing Two High-Performance I/O Design Patterns--reference

    by Alexander Libman with Vladimir GilbourdNovember 25, 2005 Summary This article investigates and co ...

  5. asp.net MVC 4.0 Controller回顾——ModelBinding实现过程

    以DefaultModelBinder为例 为简单模型绑定(BindSimpleModel)和复杂模型绑定(BindComplexModel) public virtual object BindMo ...

  6. Spring整合Struts2 注解版

    1.jar包 <!--spring配置--> <dependency> <groupId>org.springframework</groupId> & ...

  7. [Freemarker] Getting Start

    Freemarker是一个模板引擎,在.NET中有类似的T4模板,FreeMarker对ASP.NET MVC也很友好,链接地址,引用官方的一幅图 模板+数据=视图 Following are the ...

  8. ifream页面弹出框遮盖层覆盖父页面

    1.首先找到子页面上遮罩层的id, 2.然后再父页面编写个js方法 function shade() { $(".layui-layer-shade").height($(wind ...

  9. Linux查找文件内容(grep)

    转载链接:http://www.eguidedog.net/linux-tutorial/05-grep.php grep是Linux命令行下常用于查找过滤文本文件内容的命令.最简单的用法是: gre ...

  10. Spring Boot概要

    1.Spring Boot使用“习惯优于配置”(项目中存在大量的配置,此外还内置了一个习惯性的配置)的理念,使用户的项目实现快速运行.通过学习Spring Boot中的配置文件application. ...