JS学习31:关于正则全局匹配结果为奇偶真假的小疑问

1、两个简单的正则判断


  
  
  1. // 正则判断1
  2. /公司|企业|学校/g.test("123企业456");
  3. // 正则判断2
  4. /公司|企业|学校/.test("123企业456");

学过一点正则的朋友,应该知道,这两个正则判断的返回值都是true,在浏览器控制台可以直观的得到结果:

但是当我们要在判断语句中来获取正则判断1和正则判断2的结果时,却出现了奇异的现象:

从上图可以看出,正则判断1的if语句,第1次、第3次是返回的是true,而第2次、第4次返回的是false;而对正则判断2的if语句,始终返回的结果都是true。其中测试的源代码如下:


  
  
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <link rel="stylesheet" href="http://static.qianduanblog.com/css/3/last.min.css">
  7. <style>
  8. body{
  9. padding: 30px;
  10. max-width: 400px;
  11. }
  12. .divider{
  13. margin: 20px 0;
  14. border: 1px solid #ddd;
  15. }
  16. hr{
  17. height: 20px;
  18. }
  19. .ret span{
  20. margin-left: 20px;
  21. }
  22. </style>
  23. </head>
  24. <body>
  25. <p class="mb10">正则1:/公司|企业|学校/g,字符串:123企业456</p>
  26. <pre>/公司|企业|学校/g.test("123企业456");

测试结果:

正则2:/公司|企业|学校/,字符串:123企业456

/公司|企业|学校/.test("123企业456");

测试结果2:

var reg1=/公司|企业|学校/g; var reg2=/公司|企业|学校/;

var i1=0; var i2=0; $("#btn-1").click(function(){ i1++; if(reg1.test("123企业456")){ $("#div-1").append("

第"+i1+"次匹配成功

"); }else{ $("#div-1").append("

第"+i1+"次匹配失败

"); } }); $("#btn-2").click(function(){ i2++; if(reg2.test("123企业456")){ $("#div-2").append("

第"+i2+"次匹配成功

"); }else{ $("#div-2").append("

第"+i2+"次匹配失败

"); } });

2、正则的全局匹配

要解除这个疑惑,就先要明白什么是正则的全局匹配。先看个例子,有以下两个正则:


  
  
  1. var str="123abc456def789";
  2. // 正则1(非全局匹配)
  3. console.log(str.match(/\d+/));
  4. // 正则2(全局匹配)
  5. console.log(str.match(/\d+/g));

在浏览器控制台获得结果为:

其中全局匹配,匹配到了所有的数字,所以全局匹配在特定的要求下是非常有用的。并且可以发现,从控制台的返回结果的第一行,数组包含了index属性和input属性,他们分别指的是,非全局匹配的开始查找索引位置,index=0,表示从字符串str的开头开始匹配。其中index可以值可以下次获取,其名称为lastIndex,其解释为:

lastIndex属性存放一个整数,它声明的是上一次匹配文本之后的第一个字符的位置。上次匹配的结果是由方法 RegExp.exec() 和 RegExp.test() 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。lastIndex属性是可读可写的。只要目标字符串的下一次搜索开始,就可以对它进行设置。当方法 exec() 或 test() 再也找不到可以匹配的文本时,它们会自动把 lastIndex 属性重置为 0。

所以,开头说的疑问,现在可以解答了。


  
  
  1. // 全局匹配
  2. var reg1=/公司|企业|学校/g;
  3. // 从索引为0的位置开始匹配,匹配成功,最后匹配到的索引在“业”后面,其索引值为5
  4. console.log(reg1.test("123企业456"));
  5. // =>true
  6. console.log(reg1.lastIndex);
  7. // =>5
  8. // 从索引为5的位置开始匹配,但匹配失败,最后匹配到的索引在“6”后面,其索引值为8
  9. console.log(reg1.test("123企业456"));
  10. // =>false
  11. // 但因为匹配失败,所以重置为0
  12. console.log(reg1.lastIndex)
  13. // =>0
  14. // 从索引为0的位置开始匹配,匹配成功,最后匹配到的索引在“业”后面,其索引值为5
  15. console.log(reg1.test("123企业456"));
  16. // =>true

相关解释都注释在上面代码里了。开始说的疑惑,就是因为全局匹配中正则的lastIndex导致的结果,出现奇偶真假的现象也不足为怪了。那么如何解决呢?

  • 一是修改去除正则的全局匹配标志“g”。
  • 二是在判断为真的时候手动修改正则的lastIndex值。如

  
  
  1. // 全局匹配
  2. var reg1=/公司|企业|学校/g;
  3. console.log(reg1.test("123企业456"));
  4. // =>true
  5. // 匹配成功修改 lastIndex 属性
  6. reg1.lastIndex=0;
  7. console.log(reg1.lastIndex);
  8. // =>0
  9. console.log(reg1.test("123企业456"));
  10. // =>true

3、参考资料

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值