JavaScript regular expressions

JavaScript 正则表达式教程展示了如何在 JavaScript 中使用正则表达式。

正则表达式用于文本搜索和更高级的文本操作。正则表达式是内置工具,例如 grep、sed、文本编辑器(例如 vi、Emacs)以及编程语言(例如 JavaScript、Perl 和 Python)。

正则表达式

在 JavaScript 中,我们使用斜杠 //RegExp 对象构建正则表达式。

模式 是一个正则表达式,它定义了我们正在搜索或操作的文本。它由文本文字和元字符组成。元字符是控制如何计算正则表达式的特殊字符。例如,我们使用 \s 搜索空格。

创建模式后,我们可以使用其中一个函数将模式应用于文本字符串。这些函数包括testmatchmatchAllsearchreplace

下表显示了一些正则表达式:

tr>

td>

正则表达式 含义
. 匹配任何单个字符。
? 匹配前面的元素一次或根本不匹配。
+ 匹配前面的元素一次或多次。
* 匹配前面元素零次或多次。
^ 匹配字符串中的起始位置。
$ 匹配字符串中的结束位置。
| 交替运算符。
[abc] 交替运算符。
[a-c] 匹配a或b,或c。
[^abc] 范围;匹配a或b,或c。
\s 否定,匹配除a,或b,或c以外的所有内容。
\w 匹配空白字符。
[a-zA-Z_0-9] 匹配一个单词字符;相当于###

测试函数

test 方法执行正则表达式和指定字符串之间的匹配项搜索。它返回 true 或 false。

let words = ['book', 'bookworm', 'Bible',
    'bookish','cookbook', 'bookstore', 'pocketbook'];

let pattern = /book/;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

在示例中,我们有一个单词数组。该模式将在每个单词中查找“book”字符串。

let pattern = /book/;

我们使用斜线创建一个模式。正则表达式由四个普通字符组成。

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

我们遍历数组并调用test 函数。如果模式与单词匹配,它返回 true。

$ node test_fun.js
the book matches
the bookworm matches
the bookish matches
the cookbook matches
the bookstore matches
the pocketbook matches

搜索功能

search 函数返回正则表达式与给定字符串之间第一个匹配项的索引。如果未找到匹配项,则返回 -1。

let text = 'I saw a fox in the wood. The fox had red fur.';

let pattern = /fox/;

let idx = text.search(pattern);
console.log(`the term was found at index: ${idx}`);

在示例中,我们找到了“fox”项的第一个匹配项的索引。

$ node search_fun.js
the term was found at index: 8

执行函数

exec 在指定字符串中执行匹配项搜索。它返回一个包含匹配信息的对象。

let words = ['book', 'bookworm', 'Bible',
    'bookish', 'cookbook', 'bookstore', 'pocketbook'];

let pattern = /book/;

words.forEach(word => {

    let res = pattern.exec(word);

    if (res) {
        console.log(`${res} matches ${res.input} at index: ${res.index}`);
    }
});

在示例中,我们使用exec 将模式应用于输入字符串。

if (res) {
    console.log(`${res} matches ${res.input} at index: ${res.index}`);
}

我们打印有关比赛的信息。它包括匹配开始的索引。

$ node exec_fun.js
book matches book at index: 0
book matches bookworm at index: 0
book matches bookish at index: 0
book matches cookbook at index: 4
book matches bookstore at index: 0
book matches pocketbook at index: 6

匹配函数

match 函数在将模式与输入字符串匹配时检索匹配项。

let text = 'I saw a fox in the wood. The fox had red fur.';

let pattern = /fox/g;

let found = text.match(pattern);

console.log(`There are ${found.length} matches`);

在示例中,我们找出“fox”一词的出现次数。

let pattern = /fox/g;

g 字符是一个标志,用于查找所有出现的术语。通常,搜索在找到第一个匹配项时结束。

$ node match_fun.js
There are 2 matches

我们在字符串中发现了两个“fox”字词。

matchAll 函数

matchAll 函数返回所有结果的迭代器,该迭代器将字符串与正则表达式匹配。

let text = 'I saw a fox in the wood. The fox had red fur.';

let rx = /fox/g;
let matches = text.matchAll(rx);

for (let m of matches) {

    console.log(`${m} at ${m.index}`);
}

在示例中,我们找出字符串中的所有匹配项;我们还打印它们的索引。

$ node matchall_fun.js 
fox at 8
fox at 29

替换函数

replace 函数返回一个新字符串,其中部分或所有模式匹配项被替换字符串替换。

let text = 'He has gray hair; gray clouds gathered above us.'

let pattern = /gray/g;

let new_text = text.replace(pattern, 'grey');

console.log(new_text);

在示例中,我们从输入字符串创建一个新字符串,其中将“灰色”单词与“灰色”放在一起。

let pattern = /gray/g;

g 字符是一个标志,用于查找所有出现的术语。

$ node replacing.js
He has grey hair; grey clouds gathered above us.

JS 正则表达式不区分大小写匹配

要启用不区分大小写的搜索,我们使用i 标志。

let words = ['dog', 'Dog', 'DOG', 'Doggy'];

let pattern = /dog/i;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

在示例中,我们将模式应用于单词而不考虑大小写。

let pattern = /dog/i;

附加i 标志,我们进行不区分大小写的搜索。

$ node case_insensitive.js
the dog matches
the Dog matches
the DOG matches
the Doggy matches

在进行不区分大小写的搜索时,所有四个词都匹配模式。

JS 正则表达式单词边界

元字符\b 是一个锚点,它在称为单词边界的位置匹配。它允许搜索整个单词。

let text = "This island is beautiful; it is also very large.";

let rx = /\bis\b/g;
var matches = text.matchAll(rx);

for (let m of matches) {

    console.log(`${m} at ${m.index}`);
}

在示例中,我们查找 is 词。我们不想包括 Thisisland 词。

var matches = text.matchAll(rx);

使用matchAll,我们找到所有匹配项。

let rx = /\bis\b/g;

使用两个 \b 元字符,我们搜索 is 整个词。

$ node word_boundary.js 
is at 12
is at 29

JS 正则表达式子模式

子模式是模式中的模式。子模式是用 () 个字符创建的。

var words = ["book", "bookshelf", "bookworm", "bookcase", "bookish",
    "bookkeeper", "booklet", "bookmark"];

var rx = /^book(worm|mark|keeper)?$/;

for (let word of words) {

    if (word.match(rx)) {
        console.log(`${word} does match`);
    }
    else {
        console.log(`${word} does not match`);
    }
}

该示例创建了一个子模式。

var rx = /^book(worm|mark|keeper)?$/;

正则表达式使用子模式。匹配书虫、书签、记账人、书字。

$ node subpatterns.js
book does match
bookshelf does not match
bookworm does match
bookcase does not match
bookish does not match
bookkeeper does match
booklet does not match
bookmark does match

JS正则表达式点元字符

点 (.) 元字符代表文本中的任何单个字符。

let words = ['seven', 'even', 'prevent', 'revenge', 'maven',
    'eleven', 'amen', 'event'];

let pattern = /..even/;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

在示例中,数组中有八个单词。我们在每个单词上应用包含两个点元字符的模式。

$ node dot_meta.js
the prevent matches
the eleven matches

有两个词与模式匹配。

问号元字符

问号 (?) 元字符是与前一个元素匹配零次或一次的量词。

let words = ['seven', 'even', 'prevent', 'revenge', 'maven',
    'eleven', 'amen', 'event'];

let pattern = /.?even/;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

在示例中,我们在点字符后添加了一个问号。这意味着在模式中我们可以有一个任意字符,也可以没有任何字符。

$ node question_mark_meta.js
the seven matches
the even matches
the prevent matches
the revenge matches
the eleven matches
the event matches

这次没有前置字符的偶数和事件词也匹配。

JS 正则表达式锚点

锚匹配给定文本中字符的位置。使用 ^anchor 时,匹配必须出现在字符串的开头,而使用 $anchor 时,匹配必须出现在字符串的末尾。

let sentences = ['I am looking for Jane.',
    'Jane was walking along the river.',
    'Kate and Jane are close friends.'];

let pattern = /^Jane/;

sentences.forEach(sentence => {

    if (pattern.test(sentence)) {

        console.log(`${sentence}`);
    }
});

在示例中,我们有三个句子。搜索模式是^Jane。该模式检查“Jane”字符串是否位于文本的开头。 Jane\. 会在句末查找“Jane”。

JS正则表达式精确匹配

可以通过将术语放在锚点之间来执行精确匹配:^ 和 $。

let words = ['seven', 'even', 'prevent', 'revenge', 'maven',
    'eleven', 'amen', 'event']

let pattern = /^even$/;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

在示例中,我们寻找“偶数”字词的精确匹配。

$ node exact_match.js
the even matches

JS 正则表达式字符类

字符类定义了一组字符,其中任何一个字符都可以出现在输入字符串中才能成功匹配。

let words = ['a gray bird', 'grey hair', 'great look'];

let pattern = /gr[ea]y/;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`${word}`);
    }
});

在示例中,我们使用字符类来包含灰色和灰色词。

let pattern = /gr[ea]y/;

[ea] 类允许在模式中使用 ‘e’ 或 ‘a’ 字符。

命名字符类

有一些预定义的字符类。 \s匹配空白字符[\t\n\t\f\v]\d匹配数字[0-9]\w匹配单词字符[a-zA-Z0-9_]

let text = 'We met in 2013. She must be now about 27 years old.';

let pattern = /\d+/g;

while ((found = pattern.exec(text)) !== null) {

    console.log(`found ${found} at index ${found.index}`);
}

在示例中,我们在文本中搜索数字。

let pattern = /\d+/g;

\d+ 模式在文本中查找任意数量的数字集。 g 标志使搜索不会在第一次出现时停止。

while ((found = pattern.exec(text)) !== null) {

    console.log(`found ${found} at index ${found.index}`);
}

要找到所有匹配项,我们在 while 循环中使用 exec 函数。

$ node named_character_class.js
found 2013 at index 10
found 27 at index 38

在下面的示例中,我们有一个使用match 函数的替代解决方案。

let text = 'I met her in 2012. She must be now about 27 years old.'

let pattern = /\d+/g;

var found = text.match(pattern);

console.log(`There are ${found.length} numbers`);

found.forEach((num, i) => {
    console.log(`match ${++i}: ${num}`);
});

为了计算数字,我们使用\d 命名类。

$ node count_numbers.js
There are 2 numbers
match 1: 2012
match 2: 27

JS 正则表达式计数单词

在下一个示例中,我们计算文本中的单词数。

let text = 'The Sun was shining; I went for a walk.';

let pattern = /\w+/g;

let found = text.match(pattern);

console.log(`There are ${found.length} words`);

\w名称集代表一个单词字符。

let pattern = /\w+/g;

该模式使用量词 (+) 来搜索一个或多个单词字符。全局标志使搜索查找字符串中的所有单词。

console.log(`There are ${found.length} words`);

我们将字数打印到控制台。

$ node count_words.js
There are 9 words

JS 正则表达式替换

交替运算符 |创建一个具有多个选项的正则表达式。

let words = ["Jane", "Thomas", "Robert",
    "Lucy", "Beky", "John", "Peter", "Andy"];

let pattern = /Jane|Beky|Robert/;

words.forEach(word => {

    if (pattern.test(word)) {

        console.log(`the ${word} matches`);
    }
});

列表中有八个名字。

let pattern = /Jane|Beky|Robert/;

此正则表达式查找“​​Jane”、“Beky”或“Robert”字符串。

JS 正则表达式捕获组

捕获组是一种将多个字符视为一个单元的方法。它们是通过将字符放在一组圆括号内创建的。例如,(book) 是包含 ‘b’、’o’、’o’、’k’ 字符的单个组。

捕获组技术使我们能够找出字符串中与正则表达式模式匹配的部分。

content = `<p>The <code>Pattern</code> is a compiled
representation of a regular expression.</p>`;

let pattern = /(<\/?[a-z]*>)/g;

let found = content.match(pattern);

found.forEach(tag => {

    console.log(tag);
});

代码示例通过捕获一组字符来打印提供的字符串中的所有 HTML 标记。

let found = content.match(pattern);

为了找到所有标签,我们使用match方法。

$ ./capturing_groups.js
<p>
<code>
</code>
</p>

我们找到了四个 HTML 标签。

JavaScript 正则表达式电子邮件示例

在下面的示例中,我们创建了一个用于检查电子邮件地址的正则表达式模式。

let emails = ["luke@gmail.com", "andy@yahoocom",
    "34234sdfa#2345", "f344@gmail.com"];

let pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,18}$/;

emails.forEach(email => {
    if (pattern.test(email)) {

        console.log(`${email} matches`);
    } else {

        console.log(`${email} does not match`);
    }
})

这个例子提供了一种可能的解决方案。

let pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,18}$/;

第一个 ^ 和最后一个 $ 字符提供精确模式匹配。模式前后不允许有任何字符。电子邮件分为五个部分。第一部分是本地部分。这通常是公司名称、个人名称或昵称。 [a-zA-Z0-9._-]+ 列出了我们可以在本地部分使用的所有可能字符。它们可以使用一次或多次。

第二部分由文字@ 字符组成。第三部分是领域部分。它通常是电子邮件提供商的域名,例如 asyahoo 或 gmail。 [a-zA-Z0-9-]+ 是一个字符类,提供了可以在域名中使用的所有字符。+ 量词允许使用这些字符中的一个或多个。

第四部分是点字符;它前面有转义字符 (\) 以获得文字点。

最后一部分是顶级域名:[a-zA-Z.]{2,18}。顶级域可以包含 2 到 18 个字符,例如 sk、net、info、travel、cleaning、travelinsurance。最大长度可以是 63 个字符,但现在大多数域都短于 18 个字符。还有一个点字符。这是因为一些顶级域有两个部分;例如 co.uk。

$ node emails.js
luke@gmail.com matches
andy@yahoocom does not match
34234sdfa#2345 does not match
f344@gmail.com matches

在本文中,我们介绍了 JavaScript 中的正则表达式。

列出所有 JavaScript 教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏