前言
在字符串相关的操作中,很多时候我们要通过使用正则表达示来最大程序的让”机器做机器的事情“,尽量节省程序员的时间。本文中笔者将和大家探讨下JavaScript中的正则表达式的使用。
实例一
在写markdown文件时,我们有时需要对标签加锚点。如
[Tag1](#Tag1)
假设我们有很多个这样的标签,如
[Tag1][Tag2][Tag3][Tag4][Tag5][Tag6][Tag7][Tag8][Tag9][Tag10]
10个也许手动做做也快的,但是实际上可能是成百上千个。怎么样才能快速实现呢?以下为代码片段
var input = "[Tag1][Tag2][Tag3][Tag4][Tag5][Tag6][Tag7][Tag8][Tag9][Tag10]"
var step1 = input.replace(/\]\[/g,"],[");
var step2 = step1.split(',');
var step3 = [];
for(var i = 0; i < step2.length;i++){
var item = step2[i];
item = item.replace(/(\[(\w+)\])/, "$1(#$2)");
step3.push(item);
}
var step4 = step3.join(" ")
console.log(step4);
执行结果如下
[Tag1](#Tag1) [Tag2](#Tag2) [Tag3](#Tag3) [Tag4](#Tag4) [Tag5](#Tag5) [Tag6](#Tag6) [Tag7](#Tag7) [Tag8](#Tag8) [Tag9](#Tag9) [Tag10](#Tag10)
现在我们来看看这个例子中用到的两个正则表达式
第一个表达式的目的是在 ] [ 两个字符中间加一个逗号(后面用来做分割splite)。为些我们用到replace方法并采用以下正则表达式来匹配所有的 ] [ 字符。
/\]\[/g
这里有三个知识点:
1. 定义一个正则表达式的方式有两种。例子中用的是字面量形式,即以正斜线 / 开始和结束,另外还可以使用构造函数RegExp。如本例中的表达式也可以这样定义(转义符 \ 及标志 g 见下文)
new RegExp("\\]\\[", "g");
2. 转义与双重转义。在正则表达式的定义中需要使用一些有特殊用途的字符,这些字符称为元字符。包括以下14个
([{}])?*+.\^$|
需要在表达式中匹配任何一个元字符都必须对其进行转义。转义符是 \ 。在使用构造函数RegExp来构造正则表达式时,传入的参数为一个字符串,需要对所有元字符进行双重转义。如 \] 需要变为 "\\]" .
3. 标志。正则表达式只支持3个标志。g:全局模式;i:忽略大小写模式;m:多行模式。本例中为了在所有 ] [ 中加一个逗号,采用了全局模式。
第二个表达式的目的是识别出每个标签并复制其名字再加上一个 # 来加一个锚点。
/(\[(\w+)\])/
做这一步之前,我们通过split函数将字符串的每个标签都分离了出来。第二个正则表达式是针对每个字符串做操作的。这里有二个知识点:
1. 正则表达式专用特殊字符。特殊字符由上面提到的元字符及元字符与字母或者其它元字符的组合构成。这些特殊字符分别匹配其专门针对的场景。正则表达式共有37个特殊字符,除了上文提到的转义符 \ 还有36个。下面我们先看一下和本例中我们用到的特殊字符+ 类似的3个和 \w 类似的3个
字符 | 描述 |
---|---|
+ | 匹配前面紧挨的那一个表达式(一个或多个字符)1次或者多次。 |
* | 匹配前面紧挨的那一个表达式(一个或多个字符)0次或者多次。 |
? | 匹配前面紧挨的那一个表达式(一个或多个字符)0次或者1次。 |
\w | 匹配一个单字字符(所有大小写英文A-Z,a-z、数字0-9或者下划线_)。 |
\d | 匹配一个数字(即0-9)。 |
\s | 匹配一个空白字符,包括空格、制表符、换页符和换行符。 |
在本例中,我们结合使用 \w 和 + 用来匹配连续的多个字符。再加上前面的 [ 和后面的 ] 组成
/\[\w+\]/
就能匹配到一个标签(如 [Tag1] )了。
2. 捕获括号(同为37个特殊字符之一)。在正则表达式中,可以通过加一对小括号来匹配并记住符合括号内的(部分)表达式的内容。如果在一个表达式中用到了多对小括号,则记住的内容顺序为从左开始左括号的顺序。本例中使用了两组括号,第一组匹配整个字符串
/(\[\w+\])/
即匹配了 [Tag1]
第二组只匹配字符串,用来在后面加锚点,即 Tag1
/\[(\w+)\]/
当两组括号都有后就形成了我们完整的表达式
/(\[(\w+)\])/
这样我们就能同时匹配到 [Tag1] 和 Tag1 两个字符串。在捕获后如何获取到这个字符串呢?很简单,用 $ 符号加上序号,如$1将对应 [Tag1] ,$2对应 Tag1。
于是我们再通过replace函数就能达到我们加锚点的目的了
item = item.replace(/(\[(\w+)\])/, "$1(#$2)");
这个表达式对应于 [Tag1] 这个字符串做的就是
第一步,找到 [Tag1] 和 Tag1
第二步,根据后面的替换规则并将$1替换为 [Tag1] ,$2替换为 Tag1。于是结果就是[Tag1](#Tag1)。
总结
本文中我们通过一个实例讲到了基础的正则表达式的定义及37个特殊字符中的8个。同时我们还看到了正则表达式在replace方法中作为匹配模式的应用。