您的位置:首页 > Web前端 > JavaScript

说说 JavaScript 正则表达式(RegExp 对象)

2017-02-27 14:45 756 查看
语法:

var expression = / pattern / flags;


其中的 pattern 是任何简单或复杂的正则表达式。

其中的 flags 标明正则表达式的行为:

标志说明
g全局模式(**g**lobal):应用于所有字符串
i不区分大小写模式(case-**i**nsensitive):匹配时忽略大小写
m多行模式(**m**ultiline):到达一行末尾还会继续查找下一行中是否存在与模式匹配的项
举例如下:

var pattern1 = /at/g; //匹配字符串中所有存在 “at” 的实例

var pattern2 = /[bc]at/i; //匹配第一个"bat" 或 "cat",匹配时不区分大小写

var pattern3 = /.at/gi; //匹配所有以 "at" 结尾的 3 个字符组合,不区分大小写


模式中使用的所有元字符都必须转义,下面列出所有的元字符:

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


之前都是以字面量形式来定义正则表达式,下面使用 RegExp 构造函数来创建,它需要两个参数(要匹配的字符串模式、可选的标志字符串):

//匹配第一个"bat" 或 "cat",匹配时不区分大小写
var pattern = new RegExp("[bc]at","i");


由于 RegExp 构造函数的模式参数是字符串,所有里面有涉及到的所有元字符都需要双重转义。

在 ECMAScript 3 中,正则表达式的字面量有始终同一个 RegExp 实例,而使用构造函数创建的每一个新 RegExp 实例都是一个新实例,在 ECMAScript 5 中,这两种方式都会创造 RegExp 新的实例:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>ECMAScript 5 用字面量与构造函数创建的 RegExp 实例都是一个新实例</title>
</head>
<body>

<script type="text/javascript">
var re=null,i;

for(i=0;i<10;i++){
re=/den/g;
console.log(re.test("denirowweofuo"));
}

for(i=0;i<10;i++){
re=new RegExp("den","g");
console.log(re.test("denirowweofuo"));
}

</script>
</body>
</html>


1 RegExp 实例属性

属性名称类型说明
global布尔值是否设置了 g 标志
ignoreCase布尔值是否设置了 i 标志
lastIndex整数开始搜索下一个匹配项的字符位置,默认从 0 开始
multiline布尔值是否设置了 m 标志
source-正则表达式的字符串表示,按照字面量形式返回
以上这些信息没有多大的用处,因为这些信息全都包含在模式声明中:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>RegExp 实例属性</title>
</head>
<body>

<script type="text/javascript">
var pattern1=/\[bc\]at/i;
console.log(pattern1.global);//false
console.log(pattern1.ignoreCase);//true
console.log(pattern1.multiline);//false
console.log(pattern1.lastIndex);//0
console.log(pattern1.source);//"\[bc\]at"

var pattern2=new RegExp("\\[bc\\]at","i");
console.log(pattern1.global);//false
console.log(pattern1.ignoreCase);//true
console.log(pattern1.multiline);//false
console.log(pattern1.lastIndex);//0
console.log(pattern1.source);//"\[bc\]at"
</script>
</body>
</html>


2 RegExp 实例方法

2.1 exec ( )

专为捕获组设计。

接收一个参数(要应用模式的字符串)

返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回 null。

返回的数组额外包含两个属性:index(匹配项在字符串中的位置)和 input(应用正则表达式的字符串)。

返回的数组中第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则数组就只有一项):

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>RegExp 对象的 exec() 方法</title>
</head>
<body>

<script type="text/javascript">
var text="mom and dad and baby";
var pattern=/mom( and dad( and baby)?)?/gi;

var matches=pattern.exec(text);
console.log(matches.index);//0
console.log(matches.input);//"mom and dad and baby"
console.log(matches[0]);//"mom and dad and baby"
console.log(matches[1]);//" and dad and baby"
console.log(matches[2]);//" and baby"
</script>
</body>
</html>


在模式中设置了全局标志,每次调用会在字符串中继续查找新的匹配项;而如果在模式中没有设置全局标志,则每次调用同一个字符串会始终返回第一个匹配项信息:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>在全局标志下,每次调用 exec() 都会在字符串中继续查找新的匹配项</title>
</head>
<body>

<script type="text/javascript">
var text = "cat, bat, sat, fat";
var pattern1 = /.at/;

var matches = pattern1.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern1.lastIndex);//0

matches = pattern1.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern1.lastIndex);//0

var pattern2 = /.at/g;

var matches = pattern2.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern2.lastIndex);//3

matches = pattern2.exec(text);
console.log(matches.index);//5
console.log(matches[0]);//bat
console.log(pattern2.lastIndex);//8
</script>
</body>
</html>


注意: IE 在 lastIndex 的实现上与标准不一样,即使在全局模式下, lastIndex 属性每次都会变化

2.2 test ( )

接收一个字符串参数。在模式与该参数匹配的情况下返回 true;否则为 false。

使用这个方法判断目标字符串与某个模式是否匹配,很方便,所以经常被用在 if 中:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>正则表达式的 test() 方法</title>
</head>
<body>

<script type="text/javascript">
var text = "000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;

if (pattern.test(text)) {
console.log("The pattern was matched.");
}
</script>
</body>
</html>


上面这种用法经常用于验证用户输入。

RegExp 实例继承的 toLocaleString() 和 toString() 方法会返回正则表达式的字面量:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>RegExp 的 toString() 与 toLocaleString() 方法都会返回正则表达式的字面量</title>
</head>
<body>

<script type="text/javascript">
var pattern = new RegExp("\\[bc\\]at", "gi");
console.log(pattern.toString());// /\[bc\]at/gi
console.log(pattern.toLocaleString());// /\[bc\]at/gi
</script>
</body>
</html>


注意: 正则表达式的 valueOf() 方法返回正则表达式本身。

3 RegExp 构造函数属性

RegExp 构造函数包含的属性适用于所有正则表达式,并且基所执行的最近一次正则表达式操作而变化。

这些属性各有一个长的属性名称和短的属性名称(Opera 不支持短的名称):

长属性名短属性名说明
input$_最近一次要配置的字符串。(Opera 未实现)
lastMatch$&最近一次的匹配项。(Opera 未实现)
lastParen$+最近一次匹配的捕获组。(Opera 未实现)
leftContext$`input 字符串中 lastMatch 之前的文本
multiline$*是否所有表达式都使用多行模式。(IE 与 Opera 未实现)
rightContext$’input 字符串中 lastMatch 之后的文本
使用这些属性可以从 exec() 或 test() 中提取出更具体的信息:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>RegExp 构造函数属性(长属性名)</title>
</head>
<body>

<script type="text/javascript">
var text = "this has been a short summer";
var pattern = /(.)hort/g;

if (pattern.test(text)) {
console.log(RegExp.input);//this has been a short summer
console.log(RegExp.leftContext);//this has been a
console.log(RegExp.rightContext);//summer
console.log(RegExp.lastMatch);//short
console.log(RegExp.lastParen);//s
console.log(RegExp.multiple);//false

}
</script>
</body>
</html>


由于短属性名不是有效的 ECMAScript 标识符,所以必须通过方括号语法来访问:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>RegExp 构造函数属性(短属性名)</title>
</head>
<body>

<script type="text/javascript">
var text = "this has been a short summer";
var pattern = /(.)hort/g;

if (pattern.test(text)) {
console.log(RegExp.$_);//this has been a short summer
console.log(RegExp["$`"]);//this has been a
console.log(RegExp["$'"]);//summer
console.log(RegExp["$&"]);//short
console.log(RegExp["$+"]);//s
console.log(RegExp["$*"]);//false;chrome 中会返回 undefined

}
</script>
</body>
</html>


还有 9 个用于存储捕获组的构造函数属性。分为存储第一个、第二个……第九个匹配捕获组。调用 exec() 或 test() 方法时,会自动填充:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>存储捕获组的构造函数属性</title>
</head>
<body>

<script type="text/javascript">
var text = "this has been a short summer";
var pattern = /(..)or(.)/g;

if (pattern.test(text)) {
console.log(RegExp.$1);//sh
console.log(RegExp.$2);//t
}
</script>
</body>
</html>


4 模式的局限性

不支持这些高级的正则表达式特性:

匹配字符串开始和结尾的 \A 和 \Z 锚

向后查找

并集与交集

原子组

Unicode 支持

命名的捕获组

单行和无间隔匹配模式

条件匹配

正则表达式注释
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: