2021 年 12 月 12 日

字符类

考虑一个实际任务 - 我们有一个像 "+7(903)-123-45-67" 这样的电话号码,我们需要把它变成纯数字:79031234567

为了做到这一点,我们可以找到并删除任何不是数字的东西。字符类可以帮助我们做到这一点。

字符类是一种特殊符号,它匹配某个集合中的任何符号。

首先,让我们探索一下“数字”类。它写成 \d,对应于“任何单个数字”。

例如,让我们找到电话号码中的第一个数字

let str = "+7(903)-123-45-67";

let regexp = /\d/;

alert( str.match(regexp) ); // 7

如果没有 g 标志,正则表达式只查找第一个匹配项,即第一个数字 \d

让我们添加 g 标志来查找所有数字

let str = "+7(903)-123-45-67";

let regexp = /\d/g;

alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7

// let's make the digits-only phone number of them:
alert( str.match(regexp).join('') ); // 79031234567

这是一个数字的字符类。还有其他字符类。

最常用的有

\d(“d” 来自 “digit”)
一个数字:从 09 的字符。
\s(“s” 来自 “space”)
一个空格符号:包括空格、制表符 \t、换行符 \n 和一些其他罕见的字符,例如 \v\f\r
\w(“w” 来自 “word”)
一个“单词”字符:拉丁字母或数字或下划线 _。非拉丁字母(如西里尔字母或印地语)不属于 \w

例如,\d\s\w 表示一个“数字”后跟一个“空格字符”后跟一个“单词字符”,例如 1 a

正则表达式可以包含常规符号和字符类。

例如,CSS\d 匹配字符串 CSS 后面跟着一个数字

let str = "Is there CSS4?";
let regexp = /CSS\d/

alert( str.match(regexp) ); // CSS4

我们也可以使用多个字符类

alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'

匹配(每个正则表达式字符类都有相应的匹配结果字符)

反向类

对于每个字符类,都存在一个“反向类”,用相同的字母表示,但大写。

“反向”意味着它匹配所有其他字符,例如

\D
非数字:除 \d 之外的任何字符,例如字母。
\S
非空格:除 \s 之外的任何字符,例如字母。
\W
非单词字符:除 \w 之外的任何字符,例如非拉丁字母或空格。

在本章开头,我们看到了如何从类似 +7(903)-123-45-67 的字符串中提取纯数字的电话号码:找到所有数字并连接它们。

let str = "+7(903)-123-45-67";

alert( str.match(/\d/g).join('') ); // 79031234567

另一种更短的方法是找到非数字 \D 并将其从字符串中删除

let str = "+7(903)-123-45-67";

alert( str.replace(/\D/g, "") ); // 79031234567

点是“任何字符”

. 是一个特殊的字符类,匹配“除换行符之外的任何字符”。

例如

alert( "Z".match(/./) ); // Z

或者在正则表达式的中间

let regexp = /CS.4/;

alert( "CSS4".match(regexp) ); // CSS4
alert( "CS-4".match(regexp) ); // CS-4
alert( "CS 4".match(regexp) ); // CS 4 (space is also a character)

请注意,点表示“任何字符”,但不表示“字符的缺失”。必须有一个字符才能匹配它

alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot

使用“s”标志,点表示任何字符

默认情况下,点号不匹配换行符\n

例如,正则表达式A.B匹配A,然后匹配B,它们之间可以是任何字符,但不能是换行符\n

alert( "A\nB".match(/A.B/) ); // null (no match)

在很多情况下,我们希望点号能真正地匹配“任何字符”,包括换行符。

这就是标志s的作用。如果正则表达式包含它,那么点号.将匹配任何字符。

alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
IE 不支持

IE 不支持s标志。

幸运的是,有一个通用的替代方案。我们可以使用类似[\s\S]的正则表达式来匹配“任何字符”(该模式将在文章集合和范围 [...]中介绍)。

alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)

模式[\s\S]实际上表示:“空格字符或非空格字符”。换句话说,就是“任何字符”。我们可以使用其他互补类,例如[\d\D],这并不重要。甚至可以使用[^],因为它表示匹配除空字符之外的任何字符。

如果我们想要在同一个模式中使用两种“点号”,也可以使用这种技巧:实际的点号.以常规方式工作(“不包括换行符”),同时使用[\s\S]或类似的模式来匹配“任何字符”。

注意空格

通常我们不太注意空格。对于我们来说,字符串1-51 - 5几乎相同。

但是,如果正则表达式没有考虑空格,它可能无法正常工作。

让我们尝试查找由连字符分隔的数字

alert( "1 - 5".match(/\d-\d/) ); // null, no match!

让我们在正则表达式\d - \d中添加空格来修复它。

alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works
// or we can use \s class:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works

空格是一个字符。它与任何其他字符一样重要。

我们不能在正则表达式中添加或删除空格,并期望它能以相同的方式工作。

换句话说,在正则表达式中,所有字符都很重要,包括空格。

总结

存在以下字符类

  • \d - 数字。
  • \D – 非数字。
  • \s – 空格符号、制表符、换行符。
  • \S – 除 \s 之外的所有字符。
  • \w – 拉丁字母、数字、下划线 '_'
  • \W – 除 \w 之外的所有字符。
  • . – 如果带有正则表达式 's' 标志,则为任何字符,否则为除换行符 \n 之外的任何字符。

…但这还不是全部!

JavaScript 用于字符串的 Unicode 编码为字符提供了许多属性,例如:字母所属的语言(如果它是字母)、它是否是一个标点符号等。

我们也可以通过这些属性进行搜索。这需要标志 u,将在下一篇文章中介绍。

教程地图

评论

在评论之前阅读…
  • 如果您有改进建议,请 提交 GitHub 问题 或拉取请求,而不是评论。
  • 如果您不理解文章中的某些内容,请详细说明。
  • 要插入少量代码,请使用 <code> 标签,对于多行代码,请将其包装在 <pre> 标签中,对于超过 10 行的代码,请使用沙箱(plnkrjsbincodepen…)