JavaScript正则表达式进阶学习

写在前面

作为一个有理想有追求的码农,能够风骚地使用正则表达式着实是一大快事。在别人还用着循规蹈矩的方式去写业务代码时,高级的正则却可以丢上一段简短的乱码优雅地解决问题,确实很风骚,不过也不能乱用,用前权衡一下可读性和可维护性吧。
众所周知,正则表达式主要用于匹配字符串中字符组合。在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExpexectest 方法, 以及 Stringmatchreplacesearchsplit 方法。
本文主要讨论正则的用法,包括常见和进阶用法,侧重高级用法,以及尽量通俗化地解释正则表达式中一些高深概念。

常见用法

一图胜过万千言语,思路非常清晰的思维导图整理,熟悉的可以跳过这部分
https://segmentfault.com/u/sushi

以上为一个系统的概论,对于本人,平时用到的主要有:

. 匹配除换行符之外的任何单个字符

示例:表达式 a.\d,在匹配 “aaa100” 时,匹配的结果是:成功;匹配到的内容是:”aa1”;匹配到的位置是:开始于1,结束于4。

用法:/<div>(.*?)<\/div>/可以匹配div标签内有换行的数据。另外如果想匹配包含换行的全部字符,可以使用[\s\S]代替.

\s 匹配一个空白字符

包括空格、制表符、换页符和换行符。等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。

示例: /\S+/ 匹配”abc 123 @#$%”

用法:[\s\S]表示匹配任意字符,\S是\s的反义。注意区分[\s\S]与.的区别。

\ 转义

在表达式中有特殊意义,需要添加 “\” 才能匹配该字符本身的字符汇总表

字符 说明
^ 匹配输入字符串的开始位置。要匹配 “^” 字符本身,请使用 “\^”
$ 匹配输入字符串的结尾位置。要匹配 “$” 字符本身,请使用 “\$”
( ) 标记一个子表达式的开始和结束位置。要匹配小括号,请使用 “(“ 和 “)“
[ ] 用来自定义能够匹配 ‘多种字符’ 的表达式。要匹配中括号,请使用 “[“ 和 “]“
{ } 修饰匹配次数的符号。要匹配大括号,请使用 “{“ 和 “}“
. 匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 “.“
? 修饰匹配次数为 0 次或 1 次。要匹配 “?” 字符本身,请使用 “\?”
+ 修饰匹配次数为至少 1 次。要匹配 “+” 字符本身,请使用 “+“
* 修饰匹配次数为 0 次或任意次。要匹配 “*“ 字符本身,请使用 “\*“
| 左右两边表达式之间 “或” 关系。匹配 “|” 本身,请使用 “\|”

常用:

* 匹配零个或更多个,即0~n
+ 匹配一个或更多个,即至少一个,1~n
^ 字符串开始
$ 字符串结束

[]用法

使用方括号[ ]包含一系列字符,能够匹配其中任意一个字符。

表达式 可匹配
[ab5@] 匹配 “a” 或 “b” 或 “5” 或 “@”
[^abc] 匹配 “a”,”b”,”c” 之外的任意一个字符
[f-k] 匹配 “f”~”k” 之间的任意一个字母,如果要包含-字符,可以给它加上转义[\-]
[^A-F0-3] 匹配 “A”~“F”,”0”~“3” 之外的任意一个字符

示例:表达式 “[bcd][bcd]“ 匹配 “abc123” 时,匹配的结果是:成功;匹配到的内容是:”bc”;匹配到的位置是:开始于1,结束于3。

关于[]常见的错误用法是:[ab|bc]用来表示abbc,实际上,它得到的结果是[abc|],即a或b或c或|这4个字符(单字符)的任意一个。这里可以改成(ab|bc)
总结:[]里面的特殊符有五个:[]-\^,其他字符都是普通字符,包括*.?等。

次数修饰{}

使用方法是:”次数修饰”放在”被修饰的表达式”后边。比如:”[bcd][bcd]” 可以写成 “[bcd]{2}”。

表达式 作用
{n} 表达式重复n次。 “\w{2}” 相当于 “\w\w”; “a{5}” 相当于 “aaaaa”
{m,n} 表达式至少重复m次,最多重复n次。 “ba{1,3}”可以匹配 “ba”或”baa”或”baaa”
{m,} 表达式至少重复m次。 “\w\d{2,}”可以匹配 “a12”,”_456”,”M12344”
? 匹配表达式0次或者1次,相当于 {0,1}
+ 表达式至少出现1次,相当于 {1,}
* 表达式不出现或出现任意次,相当于 {0,}

如果刚好需要匹配字符{1},则正则需要给{进行转义,得到\{1}的正则。
如果{}中间不是数字,则{}本身不需要转义。

PS:这里?也可以用于非贪婪模式。

非贪婪模式
在修饰匹配次数的特殊符号后再加上一个 “?” 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 “不匹配”。这种匹配原则叫作 “非贪婪” 模式,也叫作 “勉强” 模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。

| 多个数据选一(常用于多字符)

对比[]里面的只能选一个字符功能,|常用于选取多个字符。
比如:http|ftp|svn 就需要用|分开,|的作用域是一直往后直到遇到括号,比如,对于源字符串http|ftp|svn abc匹配的结果是:’http’,’ftp’,’svn abc’。
想要匹配 http abcftp abcsvn abc就要使用括号把前边的协议括起来,如(http|ftp|svn) abc 可以得到预期的结果。

()用法

字符 含义
(x) 匹配 ‘x’ 并且记住匹配项,就像下面的例子展示的那样。括号被称为 捕获括号 。模式/(foo) (bar) \1 \2/中的 ‘(foo)’ 和 ‘(bar)’ 匹配并记住字符串 “foo bar foo bar” 中前两个单词。模式中的 \1 和 \2 匹配字符串的后两个单词。注意 \1、\2、\n 是用在正则表达式的匹配环节。在正则表达式的替换环节,则要使用像 $1、$2、$n 这样的语法,例如,’bar foo’.replace( /(…) (…)/, ‘$2 $1’ )。
(?:x) 匹配 ‘x’ 但是不记住匹配项。这种叫作非捕获括号,使得你能够定义为与正则表达式运算符一起使用的子表达式。来看示例表达式 /(?:foo){1,2}/。如果表达式是 /foo{1,2}/,{1,2}将只对 ‘foo’ 的最后一个字符 ’o‘ 生效。如果使用非捕获括号,则{1,2}会匹配整个 ‘foo’ 单词。
x(?=y) 匹配’x’仅仅当’x’后面跟着’y’.这种叫做正向肯定查找。例如,/Jack(?=Sprat)/会匹配到’Jack’仅仅当它后面跟着’Sprat’。/Jack(?=Sprat|Frost)/匹配‘Jack’仅仅当它后面跟着’Sprat’或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。
x(?!y) 匹配’x’仅仅当’x’后面不跟着’y’,这个叫做正向否定查找。例如,/\d+(?!.)/匹配一个数字仅仅当这个数字后面没有跟小数点的时候。正则表达式/\d+(?!.)/.exec(“3.141”)匹配‘141’但是不是‘3.141’

模式/(foo) (bar) \1 \2/中的 ‘(foo)’ 和 ‘(bar)’都分别为子模式,匹配结果会得到一个[1][2]的子集数据(数组下标分别是1、2)。子模式也叫分组,利用子模式,可以得到想要取出来的数据。子模式1、2、3的计算方法为左括号的计数,从左到右,从1开始,比如上面的分组1得到的是(foo)里面的数据,分组2得到(bar)里面的数据。注意这里的非捕获组和断言的左括号都是不需要数的。

常用正则匹配汇总

常用的一下正则表达式的汇总——传送门,欢迎修正补充。

进阶用法

结语

参考

  1. http://www.regexlab.com/zh/regref.htm
  2. http://www.zjmainstay.cn/my-regexp
  3. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
  4. https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F
-------------The End-------------

本文标题:JavaScript正则表达式进阶学习

文章作者:Alvabill

发布时间:2018年05月02日 - 00:05

最后更新:2018年05月12日 - 15:05

原始链接:http://alvabill.ml/JavaScript正则表达式进阶学习/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!