Regular matching, capturing, and simple application of regular

1. Understanding Regularity

• (RegExp)Regular Expression: is a built-in class of js

  1. Regularity is a rule, which can check whether a string conforms to this rule (test), or capture characters in a string that conform to a certain rule (exec, match...)
  2. Mainly used to process strings
let reg = /\d+/; // 0-9之间的数字出现1到多次
let str = 'd12fgh';
console.log(reg.test(str)); // true
console.log(reg.exec(str)); // ["12", index: 1, input: "d12fgh", groups: undefined]

2. Regular composition

• Regex consists of metacharacters and modifiers

• 正则由元字符和修饰符组成
  元字符:量词元字符、特殊元字符、普通元字符
     量词元字符:
         *: 0到多次
         +:1到多次
         ?: 0到1次
         {n}: 出现n次
         {n,}: 至少出现n次
         {n,m}: 出现n到m次
     特殊元字符:
         \ : 转义字符,可以把特殊的元字符转换为普通的元字符,也可以把普通元字符转换为特殊元字符
         . :任意字符(除了换行符意外)
         ^:以什么什么开头
         $:以什么什么结尾
         \n:换行符
         \d:0到9之间的任意数字
         \D:非0到9之间的任意数字
         \w:数字、字母、下划线
         \t:制表符
         \b:单词边界
         \s:空白符
         x|y: x和y之间的任意一个
         [a-z]:a到z之间的任意一个字符
         [a-zA-Z0-9]:a到z或者A到Z或者0到9之间的任意字符
         [^a-z]:除了a到z之外的任意一个字符
         ():分组
         (?:):只匹配,不捕获
         (?=):正向预查
         (?!):负向预查
     普通元字符:
     b
     n
     d
     ...
 修饰符:就是对正则起到修饰作用的
      i-->ignoreCase:不区分大小写
      m-->multiline:多行匹配
      g-->global:全局匹配

3. Simple use of regular expressions

  1. start and end (^$)

        // let reg = /18$/; // 以18结尾就可以
        // console.log(reg.test('189')) // false
        // console.log(reg.test('198')) // false
        // console.log(reg.test('218918')) // true
    
        // let reg = /^18$/; // 既要以18开头,又要以18结尾
        // console.log(reg.test('189')) // false
        // console.log(reg.test('198')) // false
        // console.log(reg.test('218918')) // false
        // console.log(reg.test('18e18')) // false
        // console.log(reg.test('18')) // true
    
        // let reg = /^\d{2}$/;
        // console.log(reg.test('e2')); // false
        // console.log(reg.test('2e')); // false
        // console.log(reg.test('2e2')); // false
        // console.log(reg.test('e2e')); // false
    
        // console.log(reg.test('22')); // true
        // console.log(reg.test('2')); // false
    
        // 如果 ^ $都不加,那只要出现正则里的字符就可以
        // 如果^ $都加,那匹配的字符必须跟正则的内容一样才可以
        let reg= /^123456$/;
        console.log(reg.test('000123456')); // true 只要结尾匹配上就可以
    
    1. escape character()
    // let reg = /^2.3$/;
    // . 是除了\n之外的任意字符
    // console.log(reg.test('2.3')) // true
    // console.log(reg.test('2e3')) // true
    // console.log(reg.test('2@3')) // true
    
    // 基于转义字符,把.转化成普通的元字符
    // let reg = /^2\.3$/;
    // console.log(reg.test('2.3')) // true
    // console.log(reg.test('2e3')) // false
    // console.log(reg.test('2@3')) // false
    
    // let str = '中\\国'; // 转义字符在字符串里也适用
    // console.log(str)  // '中\国'
    
    // let reg = /^\\d$/;
    // console.log(reg.test('\\d')) // true
    
    
  2. x|y : choose one between x or y

	//let reg = /^18|29$/;
    // console.log(reg.test('18')); // true
    // console.log(reg.test('29')); // true
    // console.log(reg.test('189')); // true
    // console.log(reg.test('129')); // true
    // console.log(reg.test('1829')); // true

---------------------------------------------------------------------------------------------
  
  直接写 x|y会存在很乱的优先级问题,一般我们写的时候都伴随着小括号进行分组,因为小括号改变处理的优先级 =>小括号:分组

  // let reg = /^(18|29)$/; 
        // console.log(reg.test('18')); // true
        // console.log(reg.test('29')); // true
        // console.log(reg.test('189')); // false
        // console.log(reg.test('129')); // false
        // console.log(reg.test('1829')); // false

//	():分组
        // 1、提高匹配的优先级
        // 2、分组引用
        // 3、分组捕获
            // 先捕获最大的内容,然后按照分组在依次进行捕获
            // let str = 'a3a';
            // let reg = /[a-z](\d)([a-z])/;
            // console.log(reg.exec(str)) // ['a3a','3',...]

4. Match repeated characters (abab, abbc...)

		// let str = 'moon'; 
        // ([a-z])\1:让第一次分组的字符在出现一次
        // let reg = /^[a-z]([a-z])\1[a-z]$/;
        // console.log(reg.test('moon'));
        // console.log(reg.test('mwsn'));

        // let str = 'abab';
        // let reg = /^([a-z])([a-z])\1\2$/ // 让第一次和第二次分组的字符各自再出现一次
        // console.log(reg.test('abab'))
        // console.log(reg.test('mnmn'));
        // console.log(reg.test('aaaa'))
        // console.log(reg.test('moon'))

        // let str = 'foood';
        // let reg = /^[a-z]([a-z])\1\1[a-z]$/;  // 让第一次分组的字符在出现两次
        // console.log(reg.test('foood')) // true
        // console.log(reg.test('fonod')) // true

5. Multiple digits are not allowed in []

[]中不允许出现多位数

    // let reg = /^[21-68]$/; //  2 或者 1-6 或者8 之间取一个数
    // console.log(reg.test('21')); // false
    // console.log(reg.test('68')); // false
    // console.log(reg.test('2')); // true
    // console.log(reg.test('5')); // true
    // console.log(reg.test('8')); // true

    // let reg = /^[@#ws]$/; // 中括号中的字符出现一次即可

6. Regular positive and negative preview

/* 
        正则的正负向预查:
        (?=):正向预查
        (?!):负向预查
    */ 
   // 正向预查
        //  let reg = /zhufeng(?=peixun)/; // zhufeng后面必须跟着peixun才能匹配成功
        //  console.log(reg.test('zhufengpeixunwwwwwww')); // true

        
    // 负向预查:
        // let reg = /zhufeng(?!peixun)/;// zhufeng后面必须不跟着peixun才能匹配成功
        // console.log(reg.test('zhufengwwwwwww')) // true

        // console.log(reg.test('zhufengpeixunwww')) // false

4. Regular creation method (literal value and constructor creation method)

//=>构造函数因为传递的是字符串,\需要写两个才代表斜杠
    // let reg = /\d+/g;
    // reg = new RegExp("\\d+", "g");
    // console.log(reg); // /\d+/


    //=>正则表达是中的部分内容是变量存储的值
    //1.两个斜杠中间包起来的都是元字符(如果正则中要包含某个变量的值,则不能使用字面量方式创建)
    // let type = "zhufeng";
    // reg = /^@"+type+"@$/;

    // console.log(reg.test("@zhufeng@")); //=>false
    // console.log(reg.test('@"typeeeee"@')); //=>true
    //2.这种情况只能使用构造函数方式(因为它传递的规则是字符串,只有这样才能进行字符串拼接)
    // reg = new RegExp("^@" + type + "@$");
    // console.log(reg);
    // console.log(reg.test("@zhufeng@"));//=>true

5. Regular capture

Regular capture: capture the content matched by the regular

let str = "asd123";
let reg = /\d{3}/;
let res = reg.exec(str);
console.log(res);// ["123", index: 3, input: "asd123", groups: undefined] 

// exec:他是正则实例的一个公有属性,用来捕获符合规则的内容
  1、返回值:是一个数组,如果捕获不到就是null
            1、第一项是最大的捕获内容
            2、数组的后几项是分组捕获的内容
            3、index是第一次捕获位置的索引
            4、input是原字符串

1. The laziness of regular capture
When using regular capture, only the content that meets the rules can be captured for the first time. If you want to cancel the regular laziness, add the modifier g

// 正则身上有一个lastIndex属性,他记录的是正则捕获开始的位置的索引,如果正则不加g,那不管捕获多少次lastIndex始终是0,所以每一次捕获到的都是第一次负责规则的内容(这就是正则的懒惰性)
  let str = "asd123as456as789d";
  let reg = /\d{3}/;
  // console.log(reg.lastIndex); // 0
  // console.log(reg.exec(str)); // '123'
  // console.log(reg.lastIndex); // 0
  // console.log(reg.exec(str)); // '123'
  // console.log(reg.lastIndex); // 0
  // console.log(reg.exec(str)); // '123'


// 如果正则加上g,那每一次捕获之后正则的lastIndex属性就会记录下一次开始捕获的位置的索引,当下一次再次捕获的时候就会在lastIndex的位置继续捕获(这就是取消正则的懒惰性)
  reg = /\d{3}/g;
  // console.log(reg.lastIndex) // 0
  // console.log(reg.exec(str)) // '123'
  // console.log(reg.lastIndex) // 6
  // console.log(reg.exec(str)) // '456'
  // console.log(reg.lastIndex) // 11
  // console.log(reg.exec(str)) // '789'
  // console.log(reg.lastIndex) // 16
  // console.log(reg.exec(str)) // null
  // console.log(reg.lastIndex) // 0
  // console.log(reg.exec(str)) // 跟第一次一样了 '123'

2. Encapsulate a method that captures all content (excluding group capture)

let str = "asd123as456as789d";
let reg = /\d{3}/g;

// 正则身上有一个global属性,如果当前正则没有修饰符g,那他的值就是false,反之就是true
function myExec(str){
    // 如果正则不加g,那正则的私有属性global的值就是false,
    // 如果global的值就是false那就把他捕获一次直接return出去就好了
    if(!this.global){
      return this.exec(str);
    };
    let ary = []; // 用来存放每一次捕获到的内容
    let res = this.exec(str) // 先捕获第一次
    while(res){
      // 每捕获一次就往ary里push一次捕获到的内容,直到捕获到null为止
      ary.push(res[0])
      // 然后在继续捕获
      res = this.exec(str) // 继续进行捕获
    }
    // 如果正则第一次就捕获不到,while就不会执行,那ary是空数组,直接给他return null就好了
    return ary.length === 0?null:ary;
};

 // RegExp.prototype.myExec = myExec;
 // console.log(reg.myExec(str)); // ['123','456','789']

3. The string match method
String.prototype.match()
match is a method on the string used to capture the content responsible for conforming to the rules

let str = "asd123as456as789d";
let reg = /\d{3}/g;
console.log(str.match(reg)); // ['123','456','789'] 和咱们刚才封装的方法实现的功能是一样的
// ---------------------------------------------------------------------------------------

// match的其他特点:
 let str = "{0}年{1}月{2}日";
 let reg = /\{(\d+)\}/;

//=>如果正则不设置g只会捕获一次,exec和match获取的结果一致
 console.log(reg.exec(str)); // ["{0}", "0", index: 0, input: "{0}年{1}月{2}日", groups: undefined]
 console.log(str.match(reg)); // ["{0}", "0", index: 0, input: "{0}年{1}月{2}日", groups: undefined]

//=>如果正则加上g,在多次捕获的情况下match只能把大正则匹配的内容获取到,小分组匹配的信息无法获取
 reg = /\{(\d+)\}/;
console.log(str.match(reg)); // ["{0}", "{1}", "{2}"]

4. String's matchAll method
String.prototype.matchAll()
match is a method on a string, its return value is an iterator, and each item in the iterator is all the content captured each time (large capture and group capture) [iterators can be traversed with for of]

 let str = "{0}年{1}月{2}日";
    let reg = /\{(\d+)\}/g;
    console.log(str.matchAll(reg)); // RegExpStringIterator {} 迭代器
    for (var ss of str.matchAll(reg)) {
      console.log(ss);
      // ["{0}", "0", index: 0, input: "{0}年{1}月{2}日", groups: undefined]
      // ["{1}", "1", index: 4, input: "{0}年{1}月{2}日", groups: undefined]
      // ["{2}", "2", index: 8, input: "{0}年{1}月{2}日", groups: undefined]
    }
// 去遍历当前的迭代器可以得到每一次捕获的所有内容

5. Greedyness of regularity
Greedyness of regularity capture: By default, when a regularity is captured, it is obtained according to the longest result matched by the current regularity.
Set after the quantifier metacharacter? to cancel the greediness of the regular

// 正则的贪婪性
let str = '2019';
let reg = /\d+/g;
console.log(str.match(reg)); // ['2019']

//=>在量词元字符后面设置?来取消捕获时候的贪婪性(按照正则匹配的最短结果来获取)
reg = /\d+?/g;
console.log(str.match(reg)); // ["2", "0", "1", "9"]

Guess you like

Origin blog.csdn.net/hanruo7532/article/details/112306700