var a = /([Jj]ava([Ss]cript))\sis\s(fun\w*)/;
var b = 'ffhfhjavascript is functionsdfffsff';
b.match(a)
// ["javascript is functionsdfffsff", "javascript", "script", "functionsdfffsff", index: 5, input: "ffhfhjavascript is functionsdfffsff", groups: undefined]
如果添加了修饰符g,那么返回的数组中就是多次全局模式匹配的结果
var a = /123(sxx)456(hello)/g;
var b ='123sxx456helloffffjfljfj123sxx456hellojjweww123456hello123sxx456hello';
b.match(a)
// ["123sxx456hello", "123sxx456hello", "123sxx456hello"]
var a = /123(sxx)456(hello)/g;
var b ='123sxx456helloffffjfljfj123sxx456hellojjweww123456hello123sxx456hello';
a.exec(b);
// [“123sxx456hello", "sxx", "hello", index: 0, input: "123sxx456helloffffjfljfj123sxx456hellojjweww123456hello123sxx456hello", groups: undefined]
正则
引言
作为一名合格的前端开发工程师,了解并掌握正则表达式是非常有必要的。多年的项目经验告诉我,学好正则表达式可以让我们少写很多的代码。这篇文章非常适合哪些初中级和对正则表达式掌握不是很清楚的同学,废话不多少,我门开始吧。。。
正则表达式的定义
js中的正则表达式用
RegExp
对象表示,可以使用RegExp()
构造函数来创建RegExp
对象,不过更多情况下我们使用一种特殊的直接量语法来创建,举个例子:但是如果需要我们动态的生成一个正则表达式呢,那么这个时候就需要使用构造函数形式了, 看下面的这个例子
直接量字符
正则表达式中所有的字母和数字都是按照字面量的含义进行匹配的,js的正则表达式也支持非字母的字符匹配,这些字符需要功过反斜杠
\
进行转译。下表中列举了转译字符特殊含义的符号和字符
在正则表达式中,许多标点符号具有特殊的含义,他们是:
^ $ . * + ? = ! : | \ / ( ) { } [ ]
某些符号只能在正则表达式的某些上下文中才具有某种特殊含义,在其他上下文中则会被当成直接量处理。如果想要在正则表达式中使用这些符号的直接量进行匹配,则必须使用前缀
\
,这是一条通用的规则,其他标点符号(例如@和引号)没有特殊含义,在正则表达式中按照字面量含义进行匹配,如果不记得哪些标点符号需要反斜杆转义,可以在每一个标点符号前面都加上转义符\
。另外需要注意,许多字母和数字在有反斜杆做前缀时会有特殊含义,所以对于想按照直接量进行匹配的数字和字母,尽量不要用\
进行转义字符类
将直接量字符单独放进方括号内就组成了字符类。一个字符类可以匹配它所包含的任意字符,因此表达式
/[abc]/
就和字母a,b,c中的任意一个都匹配上面的正则表达式可以匹配任意一个字母或数字,其中
a-z
表示a到z的所有字母,0-9
表示0到9之间的数字反字符类[^...]
就是匹配字符类中不含有的字符,用
^
符号开头上面的正则表达式的意思就是匹配任意一个不含有字母和数字的字符
正则表达式的字符类
正则表达式的重复语法
非贪婪模式
上面我们列举出了匹配重复字符是尽可能多的匹配,而且允许后续的正则表达式继续匹配。因此我们称之为'贪婪'匹配模式。我们同样可以使用的正则表达式进行非贪婪匹配。只需要在待匹配的字符后跟随一个问号即可:
'??', '+?', '*?' 或者'{1, 5}?'
这是因为正则表达式的模式匹配总是会寻找字符串中第一个可能匹配的位置,由于这个匹配是从字符串的第一个字符开始的,因此在这里不考虑他的子串中更短的匹配
选择,分组和引用
正则表达式语法还包括指定选择项,子表达分组和引用前一子表达式的特殊字符,我们分别来看一下
选择项:
|
用于分隔供选择的字符。/ab|cd|ef/
,可以匹配字符串ab,也可以匹配cd或者是ef。注意选择项的尝试匹配的次序是从左到右,直到发现了匹配的项。如果左边的选择项匹配,就忽略右边的选择项,即使产生更好的匹配。 所以,当正则表达式
/a|ab/
匹配字符串ab
时,他只能匹配第一个字符串a
子表达式:
正则表达式中的圆括号有多种作用。
把单独的项组合成子表达式,以便可以像处理单独的单元那样用
| * + ?
等来对单元内的项进行处理。在完整的模式中定义子模式,当一个正则表达式和目标字符串成功匹配时,可以从目标字符串中拿到和圆括号中的字符模式相匹配的部分。
()
表示捕获分组,()
会把每个分组里的匹配的值保存起来,使用$n
(n是一个数字,表示第n个捕获组的内容)(?:)
表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来引用:在同一正则表达式的后部引用前面的子表达式
这是通过在字符
\
后面加一位数字或多位数字来实现的,这个数字指定了圆括号的子表达式在正则表达式中的位置。\1, \3
分别表示正则表达式中的第一个圆括号的子表达式和第三个子表达式(注意这里指的是自表达式中匹配的文本的引用,并不是指子表达式)注意: 因为子表达式可以嵌套另一个子表达式,所以他们的位置是参与计数的左括号的位置
指定匹配位置
有一些正则表达式匹配的是字符串之间的位置,而不是实际的字符。例如
\b
匹配一个单词边界,即位于\w
和\W
之间的边界,或者是一个字符串开始或结束的位置。像\b
这样的元素不匹配某个可见的字符,他们指定匹配发生的合法位置。还有一些锚元素^ $
, 分表表示匹配字符串开始和结束的位置\b
匹配一个单词边界,即位于\w
和\W
之间的边界,或者是一个字符串开始或结束的位置。\B
匹配非单词边界。er\B
能匹配verb
中的er
,但不能匹配never
中的er
。x(?=y)
:正向先行断言,匹配x
仅仅当x
后面不跟着y
x(?!y)
:负向先行断言, 匹配x
仅仅当x
后面不跟着y
我们看下面的正则表达式,意思就是非单词边界后面跟这三个数字字符串,而且三个数字字符串后面不再跟数字
(?<=y)x
:正向后行断言,匹配x
仅仅当x
前面跟着y
(?<!y)x
:负向后行断言,匹配x
仅仅当x
前面跟的不是y
看个demo,不在小数点后加千分符
修饰符
i: 执行时不区分大小写 g: 执行一个全局匹配,简而言之,就是找到所有的匹配,而不是在找到第一个之后就停止 m: 多行匹配模式,
^
匹配一行的开头和字符串的开头,$
匹配行的结束和字符串的结束使用字面量形式时:
/\bjavascript\b/ig
构造函数形式:new RegExp('\bjavascript\b', 'ig')
用于模式匹配的String方法,string支持4种使用正则表达式的方式
search() 不支持全局匹配,会忽略修饰符g
replace()
如果第一个参数是一个string,那么
replace()
将直接搜索这个字符串然后进行替换(注意这里指替换第一个搜索到的结果),并不会先转成RegExp
进行匹配。 如果第一个参数是一个RegExp
,那么replace()
将会进行正则匹配,将第一次匹配到结果进行替换,这里正则表达式可以设置修饰符。g
会进行全局多次匹配,将所有匹配到的结果进行替换如果第二个参数是一个
string
,那么replace()
将匹配的结果直接用这个字符串替换 如果第二个参数是一个function
,我们看看可以有哪些参数: @params: 完整模式匹配到的结果 @params: 完整模式下的子模式匹配到的结果,看正则表达式中有多少个圆括号,那么这里就可以有多少个这样的参数,每个参数表示对应的子模式匹配的结果 @return: 使用return
的返回值替换匹配到的值match()
如果这个正则表达式没有设置修饰符
g
,match()
就不会进行全局检索,只检索第一个匹配。在这种情况下:数组的第一个元素就是就是完整模式匹配的结果,其余的元素则是正则表达式中圆括号的子表达式匹配的结果(如果没有圆括号就不会有这些元素)。index
表示匹配的位置,input
表示目标字符串如果添加了修饰符
g
,那么返回的数组中就是多次全局模式匹配的结果RegExp的两种方法:exec() 和 test()
exec()
如果匹配到结果就返回一个数组,结果和字符串的
match()
方法的非全局匹配返回的结果一样。但是有一点和match()
不一样,就是不管式全局还是非全局都是一样的结构。如果没有匹配到结果就返回null
test()
这个方法很简,匹配成功就返回
true
,否则就返回false
参考
javascript权威指南