《ES6标准入门(第3版)》学习笔记14:chapter_5 正则的扩展(二)

这是该系列的第14篇学习笔记!
4,y修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>y修饰符</title>
</head>
<body>
    
    <script>
    // (1)
    // ES6还提供了y修饰符,叫做“粘连”(sticky)修饰符
    // y修饰符的作用与g修饰符类似,都是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始
    // 不同点:g修饰符只要剩余的位置中存在匹配就行
    //        y修饰符会确保匹配必须从剩余的第一个位置开始,这就是“粘连”的含义

    // var s = 'aaa_aa_a';
    // var r1 = /a+/g;
    // var r2 = /a+/y;

    // console.log(r1.exec(s));  // ['aaa']
    // console.log(r2.exec(s));  // ['aaa']
    
    // console.log(r1.exec(s));   // ['aa']
    // console.log(r2.exec(s));  // null
    
    // 改一下正则表达式,保证每次都能从头部开始匹配,y修饰符就会返回结果而了
    // var s = 'aaa_aa_a';
    // var r = /a+_/y;
    // console.log(r.exec(s));   // ['aaa_']
    // console.log(r.exec(s));  // ['aa_']
    
    // (2) 使用lastIndex属性,可以更好地说明y修饰符
    // lastIndex属性指定每次搜素的开始位置,g修饰符从这个位置开始向后搜索,直到发现匹配为止
    // const REGEX = /a/g;

    // 指定从2号位置开始匹配
    // REGEX.lastIndex = 2;
    // const match = REGEX.exec('xaya');
    // console.log(match.index);  // 3

    // 下一次匹配从4号位置开始
    // REGEX.lastIndex = 4;
    // console.log(REGEX.exec('xaxa'));  // null


    // y修饰符同样遵守lastIndex属性,但是要求必须在lastIndex指定的位置发现匹配
    // const REGEX = /a/y;
    
    // 指定从2号位置开始匹配
    // REGEX.lastIndex = 2;
    // const match = REGEX.exec('xaya');
    // 不是粘连,匹配失败
    // console.log(match);  // null

    // 下一次匹配从3号位置开始
    // REGEX.lastIndex = 3;
    // const match = REGEX.exec('xaxa');
    // 3号位置是粘连,匹配成功
    // console.log(match.index);  // 3
    // console.log(REGEX.lastIndex);  // 4
    
    // (3) 进一步说,y修饰符隐含了头部匹配的标志(^)
    // console.log(/b/y.exec('aba')); // null --> 由于不能保证头部匹配
    
    // y修饰符的设计目的:让头部匹配的标志(^)在全局匹配中都有效


    // (4) 在split方法中使用y修饰符
    // ??? 原字符必须以分隔符开头,这意味着,只要匹配成功,数组的第一个成员肯定是空字符串

    
    // 找到两个匹配
    console.log('x##'.split(/#/y));  // ["x", "", ""]
    console.log('##x'.split(/#/y));  // ["", "", "x"]
    
    // ???(表示疑惑) 后续的分隔符只有紧跟前面的分隔符才会被识别
    console.log('#x#'.split(/#/y));  // ["", "x", ""]
    
    
    // (5) replace中使用y修饰符
    const REGEX = /a/gy;
    console.log('aaxa'.replace(REGEX, '-'));  // --xa --> 最后一个a不是出现在下一次匹配的头部,所以不会被替换

    // (6) match中使用y修饰符
    // 单独一个y修饰符对match方法只能返回第一个匹配,必须与g修饰符联用才能返回所有匹配
    console.log('a1a2a3'.match(/a\d/y));  // ["a"]
    console.log('a1a2a3'.match(/a\d/yg)); // ["a1", "a2", "a3"]


    // 【应用】从字符串中提取token(词元),y修饰符确保了匹配之间不会有漏掉的字符
    function tokenize(TOKEN_REGEX, str){
        let result = [];
        let match;
        while (match = TOKEN_REGEX.exec(str)){
            result.push(match[1]);
        }
        return result;
    }
    
    const TOKEN_Y = /\s*(\+|[0-9]+)\s*/y;
    const TOKEN_G = /\s*(\+|[0-9]+)\s*/g;
    
    // 字符串中无非法字符,y和g修饰符的提前结果一样
    console.log(tokenize(TOKEN_Y, '3 + 4')); // ["3", "+", "4"]
    console.log(tokenize(TOKEN_G, '3 + 4'));  // ["3", "+", "4"]

    // 字符串出现非法字符,两者的行为是不一样的
    console.log(tokenize(TOKEN_Y, '3x + 4'));  // ["3"]
    console.log(tokenize(TOKEN_G, '3x + 4'));  // ["3", "+", "4"]
    // g修饰符会忽略非法字符,而y修饰符不会!



    // console.log(TOKEN_Y.exec('3 + 4'));
    // while (match = TOKEN_Y.exec('3 + 4')){
    //         console.log('1');
    //     }


    </script>
</body>
</html>

5,sticky属性

与y修饰符相匹配,ES6的正则对象多了sticky属性,表示是否设置了y修饰符

 var r = /hello\d/y;
 console.log(r.sticky);  // true

6,flags属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>flags属性</title>
</head>
<body>
    
    <script>
    // ES6为正则表达式新增了flags属性,会返回正则表达式的修饰符

    // ES5的source属性 --> 返回正则表达式的正文
    console.log(/abc/ig.source);  // abc


    // ES6的flags属性 --> 返回正则表达式的修饰符
    console.log(/abc/ig.flags); // gi
    
    
    </script>
</body>
</html>

7,s修饰符

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>s修饰符</title>
</head>

<body>

    <script>
    // 正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是行终止符除外
    // 行终止符:换行符、回车符、行分隔符、段分隔符
    // console.log(/foo.bar/.test('foo\nbar'));  // false
    
    // 变通实现写法
    // console.log(/foo[^]bar/.test('foo\nbar'));  // true
    
    // s修饰符(dotAll模式) --> 匹配任意单个字符
    // console.log(/foo.bar/s.test('foo\nbar'));
    
    // 正则表达式还引入一个dotAll属性,返回一个布尔值,表示该正则表达式是否处于dotAll模式下
    const re = /foo.bar/s;
    // 另一种写法
    // const re = new RegExp('foo.bar', 's');
    console.log(re.test('foo\nbar')); // true
    console.log(re.dotAll);  // true
    console.log(re.flags);  // s
    

    </script>
</body>

</html>

让学习“上瘾”,成为更好的自己!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值