JavaScript-正则表达式
一、什么是正则表达式?
正则表达式也成为匹配模式(Pattern),由一组具有特定含义字符串组成,用于匹配和替换文本。
Wiki:正则表达式(英语:Regular Expression、regex或regexp,缩写为RE),也译为正规表示法、常规表示法,在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。
二、JS中定义
1.使用内建类
在javascript中我们可以通过一个内建类(RegExp)来定义一个正则表达式。
// RegEx是一个对象~注意
var regexp = new RegExp();
// 此处将会直接匹配字母p
var regexp1 = new RegExp("p");
// 第二个参数表示无视大小写匹配
var regexp2 = new RegExp("p","i");
RegExp可接受第二个参数有
g(全文查找)Global
i(无视大小写)Ignore Case
m(多行匹配)Multiple Lines
2.使用字面量
// 匹配i和I
var regexp3 = /p/i;
三、JavaScript中的正则表达式
在javascript中RegExp和String对象都有处理正则表达式的方法。
test – RegExp的test方法用来测试字符串是否匹配给出的匹配模式,返回布尔值
exec – RegExp的exec方法返回包含第一个匹配的的数组或null;
match – String的match方法返回包含所有匹配子字符串的数组;
replace – String的replace方法完成string的替换操作,支持正则表达式;
search – 与String的indexof方法类似,不同的是search支持正则表达式,而不仅仅是字符串;
split – 按照一定规则拆分字符串并将子字符串存储到数组中的String方法。
关于这些函数的具体使用方法,可以参阅JS的相关函数手册。
// test举例
var re = new RegExp("p","i");
var name = "Phoenix";
alert(re.test(name));
// 输出true
// exec举例
var re = new RegExp("p","i");
var name = "Phoenix";
alert(re.exec(name));
// 输出P
四、元字符
定义:在正则表达式中具有特殊意义的专用字符
元字符有:^ $ . * + ? = ! : | \ / ( ) [ ] { }
在使用这些符号时需要用”\”转义。
如果不清楚哪些需要转义,可以在用标点符号时候都加”\”。
五、匹配方式
1.分组匹配
上述进行了简单匹配,但实际情况并非如此。比如我们希望同时匹配0-9这10个数字。这时候我们就需要一个字符集合来进行匹配。
var re = /[0123456789]/;
var i = 5;
var j = 6;
// true
document.write(re.test(i));
// true
document.write(re.test(j));
2.范围匹配
上面栗子也就10个数,好现在要匹配26个字母,你可以从a写到z都写一遍,没问题,但是有没有觉得太长?现在范围匹配正好解决这个问题。
(p.s:这玩意的范围顺序参考ASCII码~)
var re = /[a-zA-Z]/;
var i = "x";
var j = "y";
// true
document.write(re.test(i));
// true
document.write(re.test(j));
3.取非匹配
正则表达式中也有取非操作,使用符号”^”。
var re = /[^0-9]/;
var i = 5;
var j = "y";
// false
document.write(re.test(i));
// true
document.write(re.test(j));
4.特殊匹配
可能你会觉得/[0-9]/,/[a-zA-Z]/还是不够好,好在JS提供了一套解决方案,有一些特殊字符解决了我们的麻烦,举个栗子:
// 二者等价
var re1 = /[0-9]/;
var re2 = /\d/;
常见特殊字符有:
\d 任何一个数字字符,等价于[0-9]
\D 任何一个非数字字符,等价于[^0-9]
\w 任何一个字母数字或下划线字符,等价于[a-zA-Z_]
\W 任何一个非字母数字和下划线字符,等价于[^a-zA-Z_]
\s 任何一个空白字符,包括换页符、换行符、回车符、制表符和垂直制表符,等价于[\f\n\r\t\v]
\S 任何一个非空白字符,等价于[^\f\n\r\t\v]
. 换行和回车以外的任何单个字符,等价于[^\n\r]
5.重复匹配
以匹配一个邮箱地址为例,mymail@mymail.com这样一个地址需包含一个合法用户名,@符号和一个非法的域。其中用户名和域名字符个数无法判断,但是有一点肯定,用户名必须至少一个字符,域名为两个字符和一个点构成,于是有:
var re = /\w+@\w+\.\w+/i;
var i = "mymail@mymail.com";
// true
document.write(re.test(i));
// 该匹配不完善
- “+”表示字符出现一次或多次,至少出现一次。
除了“+”可以指定至少匹配一次外,还有很多其他的可以指定匹配次数的方式。
? 出现零次或一次,最多一次
* 出现任意次(零次、一次、多次)
+ 出现一次或多次,至少一次
{n} 能且只能出现n次
{n,m} 至少出现n次,最多出现m次
6.位置匹配
var s = “_Don’t do it!”;
如何将单词“do”匹配出来?
var re = /do/gi;
上面的确实能匹配,但是Don’t也被匹配了,不是我们想要的。而在正则表达式中有专门用来进行单词边界匹配的限定符”\b”。
var reDo = /\bdo\b/gi;
“\b”到底匹配的什么呢?”\b”匹配的是一个位置,一个位于”\w“(字母,数字,下划线)和”\W“之间的位置。
既然有”\b”,那有”\B”吗?当然,他和”\b“刚好相反,由来匹配一个不是单词边界的位置。比如上例中匹配”don’t”中的”do”时”\B”就可派上用场。
var reDo = /\Bdo\B/gi;
在介绍取非匹配的时候介绍^只用位于[]并紧跟[方能取非匹配,而^还有另外一种用途——字符串边界匹配。
^ 用来匹配字符串开头
$ 用来匹配字符串结尾比如我们要匹配一个http://xxx.net形式的net域名:
var url = "http://xxx.net";
var reUrl = /^(http):\/\/xxx\.(net)$/gi;
document.write(reUrl.test(url));//true
六、贪婪匹配
它会匹配尽可能多的字符。它首先看整个字符串,如果不匹配,对字符串进行收缩;遇到可能匹配的文本,停止收缩,对文本进行扩展,当发现匹配的文本时,它不着急将该匹配保存到匹配集合中,而是对文本继续扩展,直到无法继续匹配 或者 扩展完整个字符串,然后将前面最后一个符合匹配的文本(也是最长的)保存起来到匹配集合中。所以说它是贪婪的。
<b>.*</b>
七、懒惰匹配
它会匹配尽可能少的字符,它从第一个字符开始找起,一旦符合条件,立刻保存到匹配集合中,然后继续进行查找。所以说它是懒惰的。
<b>.?</b>
贪婪匹配 | 惰性匹配 | 匹配描述 |
---|---|---|
? | ?? | 匹配 0 个或 1 个 |
+ | +? | 匹配 1 个或多个 |
* | *? | 匹配 0 个或多个 |
{n} | {n}? | 匹配 n 个 |
{n,m} | {n,m}? | 匹配 n 个或 m 个 |
{n,} | {n,}? | 匹配 n 个或多个 |