正则

正则表达式组成

普通字符

特殊字符(元字符):正则表达式中有特殊意义的字符

元字符(换行和空格算空白字符)

\d  匹配数字    [0-9]+简写

\D 匹配任意非数字字符

\w 匹配字母或者数字,下划线     [a-zA-Z_]+简写

\W 匹配不是字母,数字,下划线

\s  匹配任意空白符

\S  匹配任意不是空白符的字符

.    匹配除换行符以外的任意单字符

^   匹配行首(不是某一行)的文本(以谁开始)

$   匹配行尾文本(以谁结束)

例子 ab\d 匹配ab后面带数字  比如 ab1 ab2等等 写几个d匹配几次,比如ab\d\d 就是匹配ab11 ab22

 

限定符

是用来修饰限定符前面的字符的
 重复零次或多次

重复一次或多次

重复零次或一次

{n} 重复n次 例子\d{6} 限定数字出现6次,但是不精确,要精确匹配的话 要加上^ $ 限定符    ^\d{6}$以6位开头,以6位结束

{n,} 重复n次或者更多次(至少n,多了不限)

{n,m} 重复n到m次(至少n,最多m)

特殊字符

[ ]字符串用中括号括起来,表示匹配其中的任意字符,相当于或的意思 例子 b[oa]y 可以匹配boy bay   [1-9]匹配1-9不包括0

[ ^ ] 匹配中括号以内的内容 相当于取反

\ 转义符     

| 或者,选择左右两者中的一个

( ) 从两个直接量中选择一个,分组

eg:gr(a|e)y 匹配gray和grey

[\u4e00-\u9fa5]   匹配汉字

 正则对象

  //第一个参数 模式pattern 字符串类型
  //第二个参数 flag  i忽略大小写 g 全局匹配 字符串
  var abc=new RegExp('ab[1-9]','i');
  var abc=/ab[1-9]/i;//最常用简写方式
  var aa='Ab2';
  console.log(abc.test(aa));

 跟正则表达式相关方法

test()方法 

检测一个字符串是否匹配某个模式

exec()提取

只返回一个匹配到的结果,如果没有匹配内容则返回null

提取多个内容需要进行循环

  var str="张三:500,李四:800,王五:900";
  var reg=/\d+/g;
 do{
    var content=reg.exec(str);
    if(content){
        console.log(content[0]);
    }
 }
 while(content)

 

match()提取多个内容 

  var str="张三:500,李四:800,王五:900";
  var reg=/\d+/g;
  console.log(str.match(reg));//(3) ["500", "800", "900"]

 

 

RegExp.$1是RegExp的一个属性,指的是与正则表达式匹配的第一个 子匹配(以括号为标志)字符串

$2 $3以此类推

如果你直接在控制台打印RegExp, 出现的一定是一个空字符串: ""。那么, 我们在什么时候可以使用RegExp.$1呢?

其实RegExp这个对象会在我们调用了正则表达式的方法后, 自动将最近一次的结果保存在里面, 所以如果我们在使用正则表达式时, 有用到分组, 那么就可以直接在调用完以后直接使用RegExp.$xx来使用捕获到的分组内容, 如下:

const r = /^(\d{4})-(\d{1,2})-(\d{1,2})$/
r.exec('2019-10-08')

console.log(RegExp.$1) // 2019
console.log(RegExp.$2) // 10
console.log(RegExp.$3) // 08

 

   // 3. 分组提取  
    // 3. 提取日期中的年部分  2015-5-10
    var dateStr = '2015-1-5';
    var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/;

    reg.test(dateStr);
     reg.exec(dateStr);
    dateStr.match(reg);//三种都行

    console.log(RegExp.$1);//2015
    console.log(RegExp.$2);//1
    console.log(RegExp.$3);//5

 

trim()去除前后空格

replace() 替换

 // 1. 替换所有空白
    var str = "   123AD  asadf     asadfasf  adf ";
    // trim() 去除前后的空格
    // replace() 只能替换掉第一个查找到的内容
     console.log(str.replace(/\s/g, ''));
     第二种方法
   console.log(str.split(' ').join(''));//先切割,用空作为连接符
 
    // 2. 把所有,和,替换为.
    var str = "abc,efg,123,abc,123,a";

    console.log(str.replace(/,|,/g, '.'));

 

split()切割

 

 var str="2015/1-5";
  console.log(str.split(/[/-]/));
//(3) ["2015", "1", "5"]

 

 

search()查找

str.search(regexp)

 

此方法能够返回第一个与正则表达式regexp匹配的子字符串在str中的位置。

 

如果正则表达式没有匹配到任何内容,那方法返回-1。

 

位置是子字符串第一个字符在str中的位置。

 

字符串与数组类似,字符的位置以0为起始位置。

let str="本站的url地址是www.softwhy.com";
let reg=/\w+/g 
console.log(str.search(reg));
//3
上述代码中,正则表达式会匹配到两部分内容:

(1).url。

(2).www.softwhy.com。

但是此方法返回的是第一个匹配到字符串的第一个字符在原字符串的位置。

也就是字符"u"在字符串的位置,字符位置从0算起,它是字符串的第四个字符,所以位置是3。

 

 

 

贪婪模式和非贪婪模式

作为开始,我们先看下面的正则:

var str = 'a "witch" and her "broom" is one';
str.match( /".*"/g);

我们本来预想上面会匹配得到"witch""broom"两个字符串,运行上面的例子,却发现结果只匹配到"witch" and her "broom"一个字符串。

之所以出现这个结局,是因为正则的贪婪模式在起作用。

一、贪婪模式(默认)

首先我们假设自己是正则引擎,来模拟搜索实现的过程。
正则引擎先从字符串的第0位开始搜索。

  1. 第一个查找字符是",正则引擎在第三个位置匹配到了它:
 
 
  1. 之后,引擎尝试匹配正则的剩余部分,第二个字符是.,它代表任意字符。引擎匹配到了w:

     
     
  2. .代表任意字符重复一次到多次,因此正则引擎匹配到所有字符

     
     
  3. 当文本结束后,点的匹配停止了,但仍然有剩余的正则"需要匹配,因此正则引擎开始倒过来回溯,换句话说,就是一个字符一个字符缩减匹配。

     

     
     

    当匹配缩减后,它开始尝试匹配剩余的正则,但"没有匹配上字符e

     

  4. 因此正则继续缩减.所重复的字符,继续尝试。

 
 
  1. 正则引擎回溯,一次一次缩减.重复的字符个数,直到剩余的正则都匹配上:

     
     
  2. 现在"终于匹配上了。 如果正则是global的,正则引擎会从上次匹配结果之后继续查找更多结果。

总结:在贪婪(默认)模式下,正则引擎尽可能多的重复匹配字符。

二、非贪婪模式

非贪婪模式和贪婪模式相反,可通过在代表数量的标识符后放置?来开启非贪婪模式,如?+?甚至是??

var str = 'a "witch" and her "broom" is one';
str.match(/".*?"/g )     // "witch", "broom"

我们来看看非贪婪模式.?是怎么运转的:

  1. 第一步和上面类似,引号"被匹配上

     
     
  2. 第二步也一样, '.'被匹配上

     
     
  3. 下面是二者的重要区别。 正则引擎尝试用最小可能的重复次数来进行匹配,因此在.匹配了w后,它立即尝试"的匹配

     

     
     

    可惜没有匹配上,因为t!="

     

  4. .重复更多的字符,再进行尝试

     
     

    又没匹配上,继续~~

  5. 下面终于匹配上了


     
     
  6. 因为正则是global的,所以正则引擎继续后面的匹配,从引号后面的a字符开始,后面又匹配到第二个字符串

     
     

     

总结:在非贪婪模式下,正则引擎尽可能少的重复匹配字符。

 

posted @ 2020-05-05 22:07  Ren小白  阅读(188)  评论(0)    收藏  举报
levels of contents