Regex的一些琐碎

hwfs7278 9年前

来自: https://napw.xyz/regexde-xie-suo-sui/

最近有一些从日志里分离HTTP请求的想法,最好是能把URL彻底分解开来,这个需求自然而然是用grep了。为了方便调试,表达式是在javascript环境写的。文档看了几遍才知道,js的正则表达居然是阉割版的,几个功能没有了:

  1. look behind / negative look behind : 中文学名太长了就不写了,在url中,这个可以匹配到 # 后的 hash 但不包括 # 本身,也可以匹配 ? 后的 query 不包括 ? 本身。

  2. if-then / if-then-else : 条件表达式,这个我想对提升效率是有帮助的,假如匹配到 # 再去匹配其后的 hash ,或者匹配到 ? 时再提取后面的 query 。

  3. comment : js中提取出来的分组一般是一个数组,用0/1/2/3去访问提取结果,然而如果有注释功能的话,就可以给分组命名为 host / port / path 等等,提升代码可读性。

经过一晚上的奋斗,写出来了一个居然长达216个字符的正则表达式。匹配效果可以在 Regexpal 看到,把表达式复制到 Regexper 就可以看到匹配流程图。

这么长的表达式有存在的必要么,众所周知在Express中 req 对象什么都有,浏览器的话只要 var a = createElement(a); a.href = url; 也可以访问到url的所有属性。只有真的极端到需要在 shell 里面时才可能会有用。

这么长的表达式我很好奇性能如何,于是花了一些时间写了两个脚本,一是 URL生成器 ,用于随机生产五百万条URL并写入 records.txt ,生成的文件大约200M;二是 URL解释器 ,从文件中逐行读取记录并解析。测试结果如下: 测试进行了很多遍,结果都差不多,SSD应该可以把磁盘IO的干扰减到最小,V8引擎解析一条记录差不多是在百万分之一秒的级别,这样就没有什么优化的动力了啊。不过这只是粗略估算,大概也和我的 Intel Core i5 2.5GHz 有关系。

总之吧耗了我不少时间,最后放在grep里面还是抓不出东西来,摔。

code in github