Logo
Section 1 / 2

锚字符

学习使用锚点字符来验证文本。

导入

锚字符

学习使用锚点字符来验证文本。

锚字符的需求

让我们通过一个场景来学习锚字符的必要性。假设你需要编写一个正则表达式来匹配所有的电话记录。你从 /\d{4}-\d{3}-\d{3}/ 开始,这确实能工作,但问题在于它也会在文本 "3234-524-53134" 中返回匹配结果。然而,这不是正确的电话记录,不应该被匹配。那么,如何使用正则表达式来匹配完整的文本呢?为了匹配完整的内容,正则表达式使用了锚字符。

锚字符出现在文本的开头和结尾,也用于数据验证。

插入符字符

插入符字符创建一个否定字符集。但如果你将插入符符号放在正则表达式的最开始,它的行为会不同。插入符符号确保文本仅以指定的字符开头。

让我们通过一个例子来学习。假设你有两个文本:"123-345" 和 "abc123-456"。如果你写正则表达式 /\d{3}-\d{3}/,它会匹配两者。如果在开头加上插入符符号,你的正则表达式就变成 /^\d{3}-\d{3}/。再次运行这个正则表达式,只有以数字开头的文本才会匹配。你也可以结合分组符号使用。例如,为了提高可读性,可以写成 /^(\d{3}-\d{3})/。

在多行标志下,插入符符号同样适用。例如,要匹配以大写字母 "J" 开头的文本。正则表达式 /^J.*/ 会匹配 "Javascript"。在多行模式下,所有以大写字母 "J" 开头的行都会被匹配。

1var str = `Javascript 2javascript 3jack 4John 5elizabeth` 6 7console.log( str.match(/^J.*/g) ); 8console.log( str.match(/^J.*/gm) ); // 匹配到 John 和 Javascript 这两行

一个小挑战:使用插入符符号

编写一个正则表达式,匹配每行开头的电子邮件和电话记录。

15462-628-271 23152-362-376 abcxyz@gmail.com 3abcxyz@domain.com 44526-174-472 5abcxyz@gmail.com 4415-128-193

在下面的代码沙箱中编写,并将答案用双引号返回。

Thinking Time
Thinking Time
1var RegEx = function(){ 2 // 例如 return "/xyz/g"; 3 return ""; 4}

上述挑战的解决方案

电话格式已经明确,对应的正则表达式是 /\d{4}-\d{3}-\d{3}/。对于邮件部分,使用单词字符的简写形式,对应的正则表达式是 /\w+@\w+\.\w+/。需要注意的是,由于使用了插入符符号,必须同时使用全局标志 g 和多行标志 m。当结合这两个标志使用插入符时,正则表达式为 /^((\w+@\w+\.\w+)|(\d{4}-\d{3}-\d{3}))/gm。

注意分组的重要性。如果没有外层分组,正则引擎会将其理解为“行以邮件开头”或“包含电话记录”。

美元符号

另一个锚字符是美元符号 $。这个符号与插入符类似,唯一的区别是 $ 用于文本的末尾。

让我们用同样的文本集合来理解这一点。要匹配以大写字母 "T" 结尾的文本。正则表达式 /.*T$/ 会匹配 "JavascripT"。在多行模式下,所有以大写字母 "T" 结尾的行都会被匹配。

1var str = `JavascripT 2javascript 3hot 4heaT` 5 6console.log( str.match(/.*T$/g) ); // 匹配到 heaT 7console.log( str.match(/.*T$/gm) ); // 匹配到 JavascripT 和 heaT 这两行

在上面的代码示例中,不使用多行标志的答案是 "heaT",因为它匹配的是文本的结尾。而 "JavascripT" 位于第一行的末尾,而不是整个文本的结尾。

一个结合使用美元符号和插入符符号的挑战

编写一个正则表达式,匹配以下格式的文本。文本应以小写字母开头,且至少出现两次;接着是一个有效的电子邮件地址;最后,任何非大写字母的字符也至少出现两次。尝试使用分组使表达式更易读。

Thinking Time
Thinking Time
1var RegEx = function(){ 2 // 例如 return "/xyz/gm"; 3 return ""; 4}

上述挑战的解决方案

我们先将其分解为几个部分。文本必须以小写字母开头,且至少出现两次,因此正则表达式为 /^([a-z]{2,})/。文本结尾必须是非大写字母字符,且至少出现两次,因此正则表达式为 /([^A-Z]{2,})$/。文本中间需要包含一个有效的电子邮件地址,因此正则表达式为 /\w+@\w+\.\w+/。将所有部分组合起来,得到完整的正则表达式:/^([a-z]{2,})(\w+@\w+\.\w+)([^A-Z]{2,})$/。

单词边界

与插入符和美元符号一样,\b 也是一个锚字符,但它匹配的是单词边界。单词边界是指从单词字符到非单词字符,或从非单词字符到单词字符的位置。单词字符定义为 [0-9a-zA-Z_]。单词边界也出现在文本的开头和结尾。

考虑文本 "Hi there"

再考虑文本 " - H Car "。我们来找出其中的单词边界:

  • 第一个边界是文本的开始,但仅当文本起始为单词字符时才是。由于文本起始是非单词字符,因此这里不是单词边界。从开头到 "H" 的所有字符都是非单词字符。所以第一个单词边界是在 "H" 前面。
  • 第二个单词边界是在 "H" 后面,以及其后的空格。
  • 第三个单词边界是在 "C" 前面,即其前的空格。
  • 第四个单词边界是在 "r" 后面,即其后的空格。
1var str = " - 123 456"; 2console.log( str.match(/\b\w+\b/g) ); 3// 输出 [ '123', '456' ]

多尝试不同的文本集,以更好地掌握锚字符的使用时机和方式。

分组与选择元字符

测验