考虑一个实际任务 - 我们有一个像 "+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”)- 一个数字:从
0
到9
的字符。 \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 不支持s
标志。
幸运的是,有一个通用的替代方案。我们可以使用类似[\s\S]
的正则表达式来匹配“任何字符”(该模式将在文章集合和范围 [...]中介绍)。
alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)
模式[\s\S]
实际上表示:“空格字符或非空格字符”。换句话说,就是“任何字符”。我们可以使用其他互补类,例如[\d\D]
,这并不重要。甚至可以使用[^]
,因为它表示匹配除空字符之外的任何字符。
如果我们想要在同一个模式中使用两种“点号”,也可以使用这种技巧:实际的点号.
以常规方式工作(“不包括换行符”),同时使用[\s\S]
或类似的模式来匹配“任何字符”。
通常我们不太注意空格。对于我们来说,字符串1-5
和1 - 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
,将在下一篇文章中介绍。
评论
<code>
标签,对于多行代码,请将其包装在<pre>
标签中,对于超过 10 行的代码,请使用沙箱(plnkr、jsbin、codepen…)