话说,关于正则表达式有一个梗,大意是:

假如你有一个问题,想用正则来解决,于是你就有了两个问题

这句话侧面反映了精通正则是一件不容易的事。比如我今天遇到的诡异事件。

情景回放

这两天练手写了一个爬用户在博客园所有文章阅读量的简单爬虫。可以输出某用户的随笔总阅读量。如在命令行输入:

node index imgss

得到总阅读量是3602.

地址在readcounter;

其中有这么一段代码:

var re = /阅读\((\d+)\)/g;
while(true) {
if(!re.exec(html))//第一次调用
break; //此处会浪费一次re匹配,导致第一个匹配到的从第二个开始。
var match = re.exec(html)[1]; //第二次调用。匹配阅读量数据
console.log(match);
}

现在假设html是下面的字符串

var html=`posted @ 2017-03-17 22:32 nobody-junior 阅读(12) 评论(0)  编辑posted @ 2017-03-05 22:55 nobody-junior 阅读(29) 评论(0)  编辑posted @ 201
7-03-02 22:28 nobody-junior 阅读(588) 评论(4) 编辑posted @ 2017-02-23 18:38 nobody-junior 阅读(58) 评论(0) 编辑posted @ 2017-02-20 21:
52 nobody-junior 阅读(5) 评论(0) 编辑posted @ 2017-02-18 23:19 nobody-junior 阅读(16) 评论(0) 编辑posted @ 2017-02-14 18:45 nobody-jun
ior 阅读(9) 评论(0) 编辑posted @ 2017-02-11 20:24 nobody-junior 阅读(7) 评论(0) 编辑posted @ 2017-01-18 23:16 nobody-junior 阅读(125)
评论(0) 编辑posted @ 2017-01-06 20:38 nobody-junior 阅读(208) 评论(0) 编辑`;

运行的结果如下:



也就是跳过第一个12,匹配了29,然后跳过588,匹配到58

原因分析

没有理解re.exec的用法。阮大的文章说的很详细RegExp对象;

exec方法返回的是一个数组:比如这里返回的:

数组的第一项是匹配到的字符串,这里是阅读(12),

第二项是re中用()括起来的部分,这里是12,

第三项是原始字符串,这里是html.

以上面的为例:re=/阅读\((\d+)\)/g,用来匹配字符串中的“阅读()“部分。

在上面的while循环中,调用了两次exec方法。一次是为了判断匹配是否结束,匹配到之后,这里是”阅读(12)“没有对方法的返回值进行处理,直接进行了下一次调用。

再次调用的时候,就会跳到下一次匹配到的地方,这里是'阅读(29)',所以出现了只匹配偶数的情况。

解决

将循环部分的代码改一下:

                    while(true) {
var match = re.exec(html); //匹配阅读量数据 if(match)
console.log(match[1]);
else
break;
}

这样将每次exec方法的返回值赋值给match变量。然后对match进行匹配,不会让exec因为判断多执行一次。



这下就完全匹配了。

小爬虫完整代码:见哲理

说说正则表达式的exec方法的更多相关文章

  1. js正则表达式test方法、exec方法与字符串search方法区别

    1.正则表达式test方法 test() 方法用于检测一个字符串是否匹配某个模式 返回值: 如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 fal ...

  2. 正则表达式exec方法的陷阱

    http://www.w3school.com.cn/jsref/jsref_exec_regexp.asp exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比 test() 方法 ...

  3. js进阶正则表达式13RegExp对象方法(RegExp对象的方法:compile,test,exec)(子表达式 var reg1=/([a-z]+)\d/)

    js进阶正则表达式13RegExp对象方法(RegExp对象的方法:compile,test,exec)(子表达式 var reg1=/([a-z]+)\d/) 一.总结 1.RegExp对象有三个方 ...

  4. JavaScript中String的math方法与RegExp的exec方法的区别

    1.exec是正则表达式的方法,方法参数为字符串.match为字符串的方法,参数为正则表达式对象. 2.match与exec都返回数组.如果调用exec方法的正则表达式没有分组内容,则返回第一个匹配的 ...

  5. exec方法

    如果 exec 方法没有找到匹配,将返回 null.如果找到匹配项,则 exec 方法返回一个数组,并将更新全局 RegExp 对象的属性以反映匹配结果.数组元素 0 包含了完整的匹配项,而元素 1 ...

  6. javascript exec方法

    题目 取出 "[大哭][尴尬][发怒][发怒][调皮][调皮][呲牙]" 串中[]里面的东西 思路 正则匹配,/\[(.+?)\]/ig; exec方法循环 exec() 方法的功 ...

  7. JavaScript:exec()方法的用法及说明

    最近在看某知名js框架的源码,突然间发现自己对exec()方法竟然不太理解,然后就仔细的分析了一下这个方法 下面贴个exec()方法使用的代码出来 rquickExpr = /^(?:\s*(< ...

  8. JavaScript RegExp对象的exec()方法

    JavaScript RegExp对象的exec()方法用来匹配字符串,它的行为与match()有些不同. 对于RegExpObject.exec(),w3school上面是这样介绍的: exec() ...

  9. JavaScript RegExp.exec() 方法

    定义和用法: exec() 方法用于检索字符串中的正则表达式的匹配. 语法: RegExpObject.exec(string); RegExpObject:必须参数,正则表达式: string:必须 ...

随机推荐

  1. 工作总结(二):Web Design

    PHP框架:CakePHP 前端框架:Bootstrap Payment Data Transfer:https://developer.paypal.com/docs/classic/paypal- ...

  2. VHDL基础1

    Description Structure 一个可综合的VHDL描述中一般由3部分组成:LIBRARY declarations.ENTITY.ARCHITECTURE Library(库)用来设计重 ...

  3. (动态规划)matrix -- hdu -- 5569

    http://acm.hdu.edu.cn/showproblem.php?pid=5569 matrix Time Limit: 6000/3000 MS (Java/Others)    Memo ...

  4. 基于WebGL的三维的物联网平台技术

    参加工作三年了,从一个搞调试的民工进阶为程序员,收获还是有那么一点的.慢慢讲一些. 去年在网上发现了https://hightopo.com/cn-index.html图扑软件的基于WebGL的三维j ...

  5. Alpha阶段敏捷冲刺(二)

    1.提供当天站立式会议照片一张. 2.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中: 昨天已完成的工作. 祁泽文:上网了解了艾宾浩斯遗忘曲线算法. 徐璐琳:找交互模块的源 ...

  6. CAAnimation-CAPropertyAnimation-CABasicAnimation-CAKeyframeAnimation

    参考博客 iOS关于CoreAnimation动画知识总结 http://www.cnblogs.com/wujy/p/5203995.html iOSCoreAnimation动画系列教程(一):C ...

  7. 两个jsp文件运行后弹出对话框 下载文件问题

    这个问题是两个jsp字符编码不一致的问题 如图所示 划线部分是要特别注意的地方 出错往往是这里 有时是“;”后面有无空格 如果login.jsp有 那么loginCheck.jsp也必须要有而且是同样 ...

  8. Amoeba变形虫

    我们通过路由选择来决定操作时访问那个数据库,而路由的选择方式不外乎以下几种: 1) SpringAOP方式:spring底层配置多个数据源,配置路由(面向切面编程)手工写很多代码(废除) 2) MyS ...

  9. 2-Sat小结

    关于2-sat,其实就是一些对于每个问题只有两种解,一般会给出问题间的关系,比如and,or,not等关系,判定是否存在解的问题.. 具体看http://blog.csdn.net/jarjingx/ ...

  10. cxGrid的FilterRow默认自动匹配左边%而不是右边%

    /==============================================================================// 修改cxGrid的FilterRow ...