个性化阅读
专注于IT技术分析

JS正则表达式 – JavaScript高级教程

上一章JavaScript教程请查看:JS错误处理

在本教程中,我们将了解正则表达式如何工作,以及如何使用它们在JavaScript中高效地执行模式匹配。

什么是正则表达式?

正则表达式通常称为“regex”或“RegExp”,是一种特殊格式的文本字符串,用于在文本中查找模式。正则表达式是目前最强大的有效文本处理和操作工具之一。例如,它可以用来验证用户输入的数据格式,如姓名、电子邮件、电话号码等是否正确,查找或替换文本内容中的匹配字符串,等等。

JavaScript支持Perl风格的正则表达式。为什么使用Perl样式的正则表达式?因为Perl(实用提取和报告语言)是第一个为正则表达式提供集成支持的主流编程语言,它以对正则表达式的强大支持和非凡的文本处理和操作能力而闻名。

在深入研究正则表达式之前,让我们先简要概述一下用于执行模式匹配的常用JavaScript内置方法。

函数 解释
exec() 在字符串中搜索匹配项。如果不匹配,它将返回一个信息数组或null。
test() 测试字符串是否与模式匹配。它返回true或false。
search() 在字符串中搜索匹配项。它返回第一个匹配项的索引,如果没有找到则返回-1。
replace() 搜索字符串中的匹配项,并用替换字符串替换匹配的子字符串。
match() 在字符串中搜索匹配项。如果不匹配,它将返回一个信息数组或null。
split() 使用正则表达式将字符串分割成子字符串数组。

注意:exec()和test()方法是将字符串作为参数的RegExp方法,而search()、replace()、match()和split()方法是将正则表达式作为参数的字符串方法。

定义正则表达式

在JavaScript中,正则表达式由RegExp对象表示,它是一个原生JavaScript对象,如字符串、数组等。创建新RegExp对象有两种方法——一种是使用文字语法,另一种是使用RegExp()构造函数。

文字语法使用斜杠(/pattern/)来包装正则表达式模式,而构造函数语法使用引号(“pattern”)。下面的示例演示了创建匹配任何以“mr”开头的字符串的正则表达式的两种方法。

// 字面量语法
var regex = /^Mr\./;

// 构造函数的语法
var regex = new RegExp("^Mr\\.");

如你所见,正则表达式文字语法更短,更容易阅读,因此,最好使用文字语法,在本教程中,我们还将使用它。

注意:在使用构造函数语法时,必须双转义特殊字符,这意味着要匹配“.”,你需要写“\\.”而不是“\.”,如果只有一个反斜杠,它将被JavaScript的字符串解析器解释为转义字符并删除。

正则表达式匹配模式

正则表达式模式包括使用字母、数字、标点符号等,加上一组特殊的正则表达式字符(不要与HTML特殊字符混淆)。

在正则表达式中被赋予特殊含义的字符有:

.* ?+[](){} ^ $ | \. 当你想按字面意思使用这些字符时,你需要反斜杠。例如,如果你想匹配“.”,你必须编写\.,所有其他字符自动假定它们的字面意义。

以下各节描述了可用于制定模式的各种选择:

字符类

围绕字符模式的方括号称为字符类,如[abc],字符类总是匹配指定字符列表中的单个字符,这意味着表达式[abc]只匹配A、b或c字符。

反字符类还可以定义为匹配除括号内包含的字符之外的任何字符。反字符类的定义是将插入符号(^)放在首括号之后,就像[^abc],它匹配除A、b和c之外的任何字符。

还可以在字符类中使用连字符(-)来定义字符范围,如[0-9]。让我们来看一些字符类的例子:

RegExp 解释
[abc] 匹配字符a、b或c中的任何一个。
[^abc] 匹配除a、b或c之外的任何一个字符。
[a-z] 匹配从小写a到小写z的任意一个字符。
[A-Z] 匹配从大写字母a到大写字母z的任何一个字符。
[a-Z] 匹配从小写a到大写Z的任何一个字符。
[0-9] 匹配0到9之间的一位数字。
[a-z0-9] 匹配a和z之间或0和9之间的单个字符。

下面的示例将向你展示如何使用带有JavaScript test()方法的正则表达式查找字符串中是否存在模式

var regex = /ca[kf]e/;
var str = "He was eating cake in the cafe.";

// 根据正则表达式测试字符串
if(regex.test(str)) {
    alert("Match found!");
} else {
    alert("Match not found.");
}

此外,可以将全局标志g添加到正则表达式中,以查找字符串中的所有匹配项

var regex = /ca[kf]e/g;
var str = "He was eating cake in the cafe.";
var matches = str.match(regex);
alert(matches.length); // : 2

提示:正则表达式并不专属于JavaScript,Java、Perl、Python、PHP等语言使用相同的符号来查找文本中的模式。

预定义的字符类

一些字符类(如数字、字母和空白)使用得如此频繁,以至于它们都有快捷名称。下表列出了这些预定义的字符类:

快捷方式 解释
. 匹配除换行\n以外的任何单个字符。
\d 匹配任何数字字符,和[0 – 9]一样
\D 匹配任何非数字字符,和(^ 0 – 9)一样
\s 匹配任何空白字符(空格、制表符、换行符或回车符)。
\S 与[\t\n\r]相同
\w 匹配任何非空白字符。
\W 与[^ \t\n\r]相同

下面的示例将向你展示如何使用带有JavaScript replace()方法的正则表达式在字符串中使用连字符查找和替换空格

var regex = /\s/g;
var replacement = "-";
var str = "Earth revolves around\nthe\tSun";

// 替换空格、换行和制表符
document.write(str.replace(regex, replacement) + "<hr>");

// 只替换空格
document.write(str.replace(/ /g, "-"));

重复量词

在前一节中,我们学习了如何以各种方式匹配单个角色。但是如果你想匹配多个字符怎么办?例如,假设你想查找包含一个或多个字母p实例的单词,或者至少包含两个p的单词。

这就是量词发挥作用的地方。使用量词,你可以指定正则表达式中的字符应该匹配多少次。量词可以应用于单个字符、字符类和圆括号中包含的字符组。

下表列出了量化特定模式的各种方法:

RegExp 解释
p+ 匹配字母p的一个或多个匹配项。
p* 匹配字母p的零次或多次出现。
p? 匹配字母p的零次或一次出现。
p{2} 恰好匹配两个字母p。
p{2,3} 至少匹配两个字母p,但不超过三个。
p{2,} 匹配两个或多个字母p。
p{,3} 最多匹配三个字母p

下面示例中的正则表达式将使用JavaScript split()方法分隔逗号处的字符串、逗号序列、空格或其组合

var regex = /[\s,]+/;
var str = "My favourite colors are red, green and blue";
var parts = str.split(regex);

// 循环通过part显示子字符串
for(var part of parts){
    document.write("<p>" + part + "</p>");
}

位置定位

在某些情况下,需要在行、词或字符串的开头或结尾进行匹配。为此,你可以使用锚。两个常见的锚点是表示字符串开始的插入符号(^)和表示字符串结束的美元符号($)。

RegExp 解释
^p 匹配行首的字母p。匹配一行末尾的字母p。
p$ 匹配行首的字母p。匹配一行末尾的字母p。

下面示例中的正则表达式将只匹配名称数组中使用JavaScript test()函数以字母“J”开头的名称

var regex = /^J/;
var names = ["James Bond", "Clark Kent", "John Rambo"];

// 迭代
for(var name of names) {
    if(regex.test(name)) {
        document.write("<p>" + name + "</p>")
    }
}

模式修饰符(标识)

模式修饰符允许你控制处理模式匹配的方式。模式修饰符直接放在正则表达式后面,例如,如果希望以不区分大小写的方式搜索模式,可以使用i修饰符,例如:/ Pattern /i。

下表列出了一些最常用的模式修饰符。

修饰符 解释
g 执行全局匹配,即查找所有发生的事件。
i 使匹配不区分大小写。
m 更改^和$的行为以匹配换行边界(即多行字符串中的每一行的开始或结束),而不是字符串边界。
o 仅对表达式求一次值。
s 改变的行为。(点)匹配所有字符,包括换行符。
x 允许你在正则表达式中使用空白和注释以保持清晰。

下面的示例将向你展示如何在正则表达式中使用g和i修饰符来使用JavaScript match()方法执行不区分大小写的全局搜索。

var regex = /color/gi;
var str = "Color red is more visible than color blue in daylight.";
var matches = str.match(regex); // 全局不区分大小写的匹配
console.log(matches);
// : ["Color", "color"]

类似地,下面的示例展示了如何使用^锚和m修饰符以及JavaScript match()方法在多行字符串的每一行的开头进行匹配。

var regex = /^color/gim;
var str = "Color red is more visible than \ncolor blue in daylight.";
var matches = str.match(regex); // 全局,不区分大小写,多行匹配
console.log(matches);
// : ["Color", "color"]

交替

交替允许你指定模式的替代版本,正则表达式中的替换就像if-else条件语句中的OR操作符一样工作。

可以使用竖线(|)指定替换。例如,regexp /fox|dog|cat/匹配字符串“fox”,或字符串“dog”,或字符串“cat”。这里有一个例子:

var regex = /fox|dog|cat/;
var str = "The quick brown fox jumps over the lazy dog.";
var matches = str.match(regex);
console.log(matches);
// : ["fox", index: 16, ...]

注意:从左到右计算备选项,直到找到匹配项为止,如果左可选项匹配,则即使有匹配项,也会完全忽略右可选项。

分组

正则表达式使用括号将子表达式分组,就像数学表达式一样,圆括号允许将重复量词应用于整个子表达式。

例如,在regexp /go+/量词+只应用于最后一个字符o,它匹配字符串“go”、“goo”等。然而,在regexp /(go)+/量词+应用于字符g和o组,它匹配字符串“go”、“gogo”等。

var regex = /(go)+/i; 
var str = "One day Gogo will go to school.";
var matches = str.match(regex); // 不区分大小写的匹配
console.log(matches);
// : ["Gogo", "go", index: 8, ...]

注意:如果字符串与模式匹配,match()方法将返回一个数组,其中包含作为第一个元素的整个匹配字符串,然后是括号中捕获的任何结果,以及整个匹配的索引。如果没有找到匹配项,则返回null。

提示:如果正则表达式包含g标志,match()方法只返回一个包含所有匹配子字符串的数组,而不是match对象。不返回捕获的组、整个匹配的索引和其他属性。

单词边界

单词边界字符(\b)帮助你搜索以模式开头和/或结尾的单词。例如,regexp /\bcar/匹配以模式car开头的单词,并将匹配cart、carrot或cartoon,但不匹配oscar。

类似地,regexp /car\b/匹配以模式car结尾的单词,并将匹配oscar或supercar,但不匹配cart。同样,/\bcar\b/将开头和结尾的单词与模式car匹配,并且只匹配单词car。

下面的示例将突出显示以car开头的粗体单词:

var regex = /(\bcar\w*)/g;
var str = "Words begining with car: cart, carrot, cartoon. Words ending with car: oscar, supercar.";
var replacement = '<b>$1</b>';
var result = str.replace(regex, replacement);
document.write(result);
赞(0)
未经允许不得转载:srcmini » JS正则表达式 – JavaScript高级教程

评论 抢沙发

评论前必须登录!