正则表达式知识点总结

正则表达式常用知识点总结

一、正则表达式知识点记录

  • 备忘单
1.字符类
    .	      匹配除了换行符(\n)以外的任意一个字符
    \w		  任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个
    \d		  任意一个数字,0~9 中的任意一个
    \s	      包括空格、制表符、换页符等空白字符的其中任意一个
    \W\D\S  非字母, 数字, 空白字符
    [abc]	  匹配a、 b、或c中的任何一个
    [^abc]	  匹配 a、b和c之外的任何一个
    [a-g]	  a-g间的任意一个字符
2.锚
    ^abc$	    字符串的开头/结尾
    \b \B	    单词边界、非单词的边界
    转义字符
    \. \* \\	转义特殊字符
    \t\n\r	    制表符, LF换行符, CR换行符
3. 分组 & 前瞻后顾
	(abc)	   捕获分组
    \1	       反向引用#1
    (?:abc)	   不捕获分组
    (?=abc)	   正向前瞻
    (?!abc)	   负向前瞻
4.量词 & 分支
    a* a+ a?   0个或更多,1个或更多,0个或1个
    a{5} a{2,} 刚好5个,2个或以上
    a{1,3}	   1~3个
    a+? a{2,}? 贪婪匹配(仅可能少匹配)
    ab|cd	   配 ab 或 cd

二、部分疑难标识解读

  • \b 匹配单词边界

  • (?=abc)正向先行断言,表示主表达式后面必须包含abc,且该组不会出现在结果中,如果一个正则中包含多个断言,则没有先后顺序

如:提取包含至少一个大小写字母的字符串:
正则表达式:/(?=.*?[A-Z])(?=.*?[a-z]).+/g和正则表达式/(?=.*?[a-z])(?=.*?[A-Z]).+/g都可以
注意:零宽断言只匹配位置,没有改变位置。
如:密码强度验证:
	至少一个大写字母
	至少一个小写字母
	至少一个数字
	至少8个字符
正则表达式为:/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/ 中间的.*不可少,如果改为/(?=\d)(?=[a-z])(?=[A-Z]).{8,}/则不正确,因为无法找到一个位置同时满足三个断言,前一个断言,匹配到的位置为0
  • (?<=abc)正向后行断言
先行断言和后行断言只有一个区别,即先行断言从左往右看,后行断言从右往左看。即一个先行断言是后面有什么,后行断言就是前面有什么。
匹配名字中含王,但不在最后一个字同学的名字 /(?<=王).+?/
  • (?!abc) 反向先行断言
正则表达式匹配不是qq邮箱的数据 /@(?!qq)/
编写正则表达式匹配除<p>或</p>之外的所有标签。 正则表达式应该是/<(?!p|\/p).*>/不能是/(?!<p>|<\/p>)/如果这么写
<p></p>或<p>code</p>都能匹配上,匹配的位置是1,及<这个字符
  • (?<!abc)正反向后行断言
前面没有什么
  • replace方法的使用

    基本语法:stringObject.replace(regexp/substr,replacement)

    • 当replace方法的第一个参数为一个字符串时,将只会替换第一个匹配的字符串并替换
    var str='讨论一下正则表达正则式中的replace的用法';
    var d =str.replace('正则','测试'); // '讨论一下测试表达正则式中的replace的用法'
    
    • replacement可以是字符串也可以是函数,其中的$有特殊意义
    字符 替换文本
    $1、$2、…、$99 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。
    $& 与 regexp 相匹配的子串。
    $` 位于匹配子串左侧的文本。
    $’ 位于匹配子串右侧的文本。
    $$ 直接量符号。
    • replacement如果为一个函数时,总共有四个参数
      • 匹配模式的字符串
      • 匹配模式字符串中的子表达式,及分组数据
      • 匹配的位置,index
      • 原字符串
    例:把字符串中所有单词的首字母都转换为大写:
    let name = 'aaa bbb ccc';
    let uw=name.replace(/\b\w+\b/g, function(word){
      return word.substring(0,1).toUpperCase()+word.substring(1);}
    );
    
  • match方法的使用

    • 基本用法:
    // 用法一:匹配一个字符串
    stringObject.match(searchvalue)
    // 用法二:匹配一个正则表达式
    stringObject.match(regexp)
    
    • 如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null
    • 不加全局标志g,如果找到,则会返回一个数组,数组中依次包含以下几项
      • 第0个元素,匹配的文本
      • 其余的元素存放的是与正则表达式的子表达式匹配的文本
      • index属性,匹配的index位置
      • input属性,及stringObject
    • 加全局标志g,如果找到吗,则会返回一个数组,数组中只有上面的第一项,即只用具体匹配的值,如果加了全局标志g,还想像上面返回的数组格式一样,可以用 下面介绍的exec方法
    // 不加全局标志g
    var str="Hello world!"
    console.log(str.match(/ello/)) //['ello', index: 1, input: 'Hello world!', groups: undefined]
    var str="sdf55sdf23"
    console.log(str.match(/[a-zA-Z](\d+)/)) // ['f55', '55', index: 2, input: 'sdf55sdf23', groups: undefined]
    // 加全局标志g
    var str="1 plus 2 equal 3"
    console.log(str.match(/\d+/g)) // ['1', '2', '3']
    
  • exec方法的使用

    • 基本用法
    RegExpObject.exec(string)
    
    • 返回格式和match方法基本相同,如果不加全局标志g,match方法的返回结果和exec方法的数组是相同的
    • 但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0
    var str = "Visit W3School, W3School is a place to study web technology."; 
    var patt = new RegExp("W3School","g");
    var result;
    while ((result = patt.exec(str)) != null)  {
      console.log('result:',result)
      console.log('lastIndex:',patt.lastIndex)
    }
    //打印如下:
    result: ['W3School', index: 6, input: 'Visit W3School, W3School is a place to study web technology.', groups: undefined]
    lastIndex: 14
    
    result: ['W3School', index: 16, input: 'Visit W3School, W3School is a place to study web technology.', groups: undefined]
    lastIndex: 24
    
  • search方法的使用

    • 基本语法
    //用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。,返回stringObject 中第一个与 regexp 相匹配的子串的起始位置。如果没有找到任何匹配的子串,则返回 -1
    stringObject.search(regexp)
    
    • 注意:search() 方法不执行全局匹配,它将忽略标志 g。它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。
  • split方法的延伸

    • 利用正则对字符串转数组,提取关键字,去除不必要的字符(常用)
    let str="Tom,What  are  you   doing   today"
    let strArr = str.split(/[,\?\s]+/)
    console.log(strArr) // ['Tom', 'What', 'are', 'you', 'doing', 'today']
    

三、部分正则表达式示例

  • president@whitehouse.gov是匹配模式/1+@[A-Z0-9.-]+.[A-Z]{2,6}$/的有效的Email地址。(错误)
应该改写为/^[A-Z0-9a-z._%+-]+@[A-Z0-9a-z.-]+\.[A-Za-z]{2,6}$/
注意点:字符集集合([])中.([.])代表的是单个字符,不是代表匹配任意一个除换行符以外的元素
  • 假设日期有以下格式2020-01-02、2020-1-2、2020.01.02、2020 01 02、2020 1 2、20200102、2020/01/02,并且需要提取其中的年月日,则正则表达式可以写成/(\d{4})[.-/\s]?(\d{1,2})[.-/\s]?(\d{1,2})/ (错误)
应该写成/(\d{4})[-./\s]?(\d{1,2})[-./\s]?(\d{1,2})/
[.-/]会被解析成 从 字符(.)到字符(/)的范围,字符(.)ASCII码为46,字符(/)ASCII码为47,字符(-)ASCII码为45

四、常用正则表达式梳理

  • 整理中。。。。

  1. A-Z0-9._%± ↩︎

上一篇:AbstractQueuedSynchronizer::tryAcquireNanos源码笔记


下一篇:多线程同步器之CountDownLatch