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

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

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

情景回放

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

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. 实现两个sym转一个sym

    CVO输出如果是一个像素并行输出,选择内嵌人插入同步码.如果两个像素并行输出是不能选择内嵌的,只能选择分离的方式.如果把输出的并行数据给VIP并且要求是内嵌,那只能在内部转或者外部转. 这里是实现外部 ...

  2. Unicode 字符

    Unicode是计算机可以支持这个星球上多种语言的秘密武器.在Unicode之前,用的都是ASCII. ASCII码非常简单,每个英文都是7位二进制的方式存贮在计算机内,其范围是32~126.当用户在 ...

  3. vue.js入门学习

    可以用淘宝npm镜像 然后安装 然后初始化项目: Watch就是一个监听 v-if是如果为false就根本不在页面存在这个元素 v-show是通过display:none来控制这个元素的显示和隐藏 r ...

  4. Python自动化开发 - 字符编码、文件和集合

    本节内容 字符编码 文件操作 集合 一.字符编码 1.编码 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.解决思路:数字与符号建立一对一映射,用不同数字表示不同符号. ASCI ...

  5. poj1573模拟

    Robot Motion Time Limit: 1000 MS Memory Limit: 10000 KB 64-bit integer IO format: %I64d , %I64u Java ...

  6. XML Publisher 并发程序由于"输出提交处理程序提交失败

    http://www.cnblogs.com/benio/archive/2012/03/30/2424900.html xmlp 报表运行完成后,状态为warning,其原因大概有以下3类:1.&q ...

  7. cxGrid实现取消过滤和排序后定位到首行(单选和多选)

    cxGrid实现取消过滤和排序后定位到首行(单选和多选) 原创 2013年10月06日 18:42:24 2107 DataContoller中的函数FocusedRecordIndex没有反应,Fo ...

  8. delphi 小数点四舍五入问题

    function ARoundN(v: Double; n: Integer): Double; var I:Integer; begin result:=v; do begin result:=re ...

  9. Excel中单元格、超级链接形成超级链接单元格

    使用函数 HYPERLINK(超链接,显示文字) =HYPERLINK("http://www.cnblogs.com/Vpygamalion/","李汉超") ...

  10. [leetcode.com]算法题目 - Plus One

    Given a number represented as an array of digits, plus one to the number. class Solution { public: v ...