7

为什么要使用正则表达式

正则表达式通过由普通字符和特殊字符组成的文字模板完成对字符串的校验,搜索,替换。在javascript中类似这样

/^1\d{10}$/

上面的这个简单的正则用来匹配手机号
至于说正则表达式到底有什么意义,借由《精通正则表达式》里面的一句话来概括好了。

​ “如果罗列计算机软件领域的伟大发明,我相信绝对不会超过二十项,在这个名单当中,当然应该包括分组交换网络,Web,Lisp,哈希算法,UNIX,编译技术,关系模型,面向对象,XML这些大名鼎鼎的家伙,而正则表达式也绝对不应该被漏掉。
​对很多实际工作而言,正则表达式简直是灵丹妙药,能够成百倍的提高开发效率和程序质量。”

正则表达式的生成

在javascript中生成正则表达式的方式有两种

  1. 调用RegExp对象的构造函数

    var reg = new RegExp('^[a-z]+[0-9]$', 'gi')

    其中第一个参数是匹配模式,第二个参数是可选参数(g, i, m),分别用于指定全局匹配、区分大小写的匹配和多行匹配。这种方式会在正则表达式运行时编译(runtime compilation)。如果你知道正则表达式模式将会改变,或者你事先不知道什么模式,而是从另一个来源获取,如用户输入,这些情况都可以使用构造函数。

  2. 使用正则表达式字面值,将匹配模式封闭在两个斜杠中

    var reg = /^[a-z]+[0-9]$/gi

    当表达式被赋值时,字面量形式提供正则表达式的编译(compilation),当正则表达式保持为常量时一般使用字面量方式。例如当你在循环中使用字面量构造一个正则表达式时,正则表达式不会在每一次迭代中都被重新编译(recompiled)

正则表达式的组成

正则表达式的文字模板是有很多不同类型的字符组成的,包括:
元字符,转义字符,限定符,字符组,或结构,括号分组

元字符

字符 含义
. 匹配除了换行符(n)以外的所有字符
w 匹配字母,数字,下划线
W 匹配除了字母,数字,下划线以外的其他字符
d 匹配数字
D 匹配除了数字以外的其他字符
s 匹配任意的空白符(f, n, r, t, v)
S 匹配空白符以外的任意字符
b 匹配单词的开始或者结束
B 匹配单词的非开始或者结束
^ 匹配行首
$ 匹配行尾

转义字符

* + ? | { [ ( ) ] }^ $ . # 和 空白 这些字符都是需要转义的。例如我们要匹配{。

\{

限定符

字符 含义
* 匹配零次至多次
+ 匹配一次至多次
匹配零次或一次
{2,} 至少匹配两次
{10} 匹配10次
{{2, 8}} 至少匹配两次之多匹配八次

字符组[]

中括号字符组用来匹配括号内的字符之一

'fasfagxfasdfyfasfz'.split(/[xyz]/) //["fasfag", "fasdf", "fasf", ""]

还有一种排除性字符组

'xaxbycz'.split(/[^xyz]/)   //["x", "x", "y", "z"]

或结构 |

例如c|d匹配或者d

/c|d/.test('af') // false
/c|d/.test('ad') // true

括号分组

(cd){1,} 可以匹配cdcd..等, 其中cd便是一个分组。

    /(cd){1,}$/.test('cdcd') //true

贪婪模式和非贪婪模式

默认情况下,所有的限定词都是贪婪模式,表示尽可能多的去捕获字符。而在限定词后增加“?”,则是非贪婪模式,表示尽可能少的去捕获字符。

'ccccccd'.match(/c+/) //["ccccc"], 贪婪模式, 捕获所有
'ccccccd'.match(/c+?/) //["c"], 非贪婪模式, 只捕获到第一个

捕获分组

在实际应用中我们很有可能需要获取到匹配的字符串,例如我们要将字符串"万里碧空飘着朵朵白云"替换成"万里碧空没有一朵白云"

"万里碧空飘着朵朵白云".replace(/(万里碧空)飘着朵朵白云/, '$1没有一朵白云')

捕获性分组会创建反向引用,js中可以通过 $+number 或者 "反斜杠"+number" 表示法进行引用。

注意:

反斜杠+number这种引用可以在正则表达式中使用,可用于匹配不同位置的相同子串,例如:

'www.bai.bai.com'.replace(/([a-z]+)\.\1/, '$1') // www.bai.com

非捕获性分组

非捕获性分组,通常由一对括号加上”?:”加上子表达式组成,非捕获性分组不会创建反向引用,就好像没有括号一样。捕获性分组和无捕获性分组在搜索效率方面也没什么不同,没有哪一个比另一个更快。

/^(?:\d+)/

正则表达式的方法

test

检索字符串中的指定子串,返回布尔值

/^\d[a-zA-Z]{3}$/.test('1aac') // true

exec

返回一个数组,数组中的第一个条目是第一个匹配

/^\d[a-zA-Z]{3}$/.exec('1aac') // ["1aac"]

String可以使用正则表达式的方法

search

返回子串的开始位置

'a12b2334c34'.search(/\d{4}/) // 4

match

返回匹配到的子串

'a12b2334c34'.match(/\d{4}/) // ["2334"]

replace

替换匹配到的子串

'a12b2334c34'.replace(/\d{4}/, 'cccc') // "a12bccccc34"

split

将字符串分割成数组

'a12b2334c34'.split(/\d{4}/)  // ["a12b", "c34"]

断言

正向先行断言 (?=exp)

代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配 exp

/f(?=234)/.test('123abcf234acd') //true

负向先行断言(?!exp)

代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配 exp

/f(?!234)/.test('123abcf234acd') //false

常用的正则表达式

Email 地址:

^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

URl验证

[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

密码验证

(?!^[0-9]+$)(?!^[A-z]+$)(?!^[^A-z0-9]+$)^[^\s\u4e00-\u9fa5]{6,16}$

邮编验证

[1-9]d{5}(?!d)

手机号码验证

^1\d{10}$

汉字验证

^[\u4e00-\u9fa5]{0,}$

wupengyu
1.8k 声望166 粉丝

写作是为了更好的思考