Python处理正则表达式超时的办法
最近在项目中遇到一个问题,就是需要采用正则匹配一些疑似暗链和挂马的HTML代码,而公司的老大给的正则表达式有的地方写的不够严谨,导致在匹配的时候发生卡死的现象,而后面的逻辑自然无法执行了。虽然用正则表达式来判断暗链和挂马可能不那么准确或者行业内很少有人那么做,但是本文不讨论如何使用正确的姿势判断暗链挂马,只关注与正则超时的处理。
在使用正则表达式的时候,如果正则写的太糟糕,所消耗的时间是惊人的,并且有可能会一直回溯,而产生卡死的现象,所以一般的大型公司都会有专门的人来对正则进行优化,从而提高程序效率。一般来说如果可能的话不要让用户来输入正则进行匹配。但是现在既没有专门的人进行正则的优化,本人也对正则了解的不够,所以只能从另外的角度来考虑处理超时的问题。
首先我想到的方法是另外开启一个线程来进行匹配,而在主线程中进行等待,如果发现子线程在规定的时间内没有返回就kill掉子线程。这也是一个方案,但是我现在要介绍另外一种方案,该方案来自我在网上看到的一篇博客.
该博客给出了另外一种办法,就是采用信号的方式,在正则匹配之前定义一个信号,并规定触犯时间和处理的函数,如果在规定时间内程序没有结束那么触发一个TimeoutError的异常,而主线程收到这个异常时就会中断执行,并处理这个异常,这样就从正则匹配中解脱出来,达到了我们要的结果。这个方法有两个不足之处:
- 信号这个东西是Linux独有的,在Windows下不适用
- 信号只能在主线程中使用,而如果在子线程中进行正则匹配,那么这个方法就不适用
我的项目正在运行在Linux系统上,所以针对第一个不足来说可以接受,但是我的正则匹配都是在子线程中,所以乍看之下这个方案也不太靠谱,但是好在我在后面的评论中发现博主给出了针对第二种不足的解决方案——开辟一个子进程,将正则匹配放到子线程中,这样一来可以充分利用多核(毕竟Python中的多线程是个伪多线程),二来可以分方便的使用该方案解决问题,下面是实际的代码
import re
import multiprocessing
import signal
def time_out(b, c):
raise TimeoutError
def search_with_timeout(pipe, word, value):
signal.signal(signal.SIGALRM, time_out)
signal.alarm(1)
r = re.compile(word)
try:
ret = r.search(value, re.I)
b_ret = True if ret != None else False
pipe.send(b_ret)
except TimeoutError:
pipe.send(False)
在上面的代码中先的定义了一个信号,给定1s中以后触发,触发的函数为time_out然后执行正则表达式,如果在这1s中内无法完成,那么处理函数会被调用,会跑出一个异常,此时主线程终止当前任务的执行,进入到异常处理流程,这样就可以终止正则匹配,从而正常的返回。由于这个部分是一个新进程自然就涉及到不同进程之间的通信,在这个例子中我使用了管道进行通信。由于Python在创建子进程的时候可以进行参数的传入所以我只需要一个管道将数据从子进程中写入,再从朱金城中读取就好了。
下面是调用该子进程的代码:
pipe = multiprocessing.Pipe()
p = multiprocessing.Process(target = search_with_timeout, args = (pipe[0], word, left_value))
p.start()
p.join() #等待进程的结束
ret = pipe[1].recv() #获取管道中的数据
Python处理正则表达式超时的办法的更多相关文章
- python study - 正则表达式
第 7 章 正则表达式 7.1. 概览 7.2. 个案研究:街道地址 7.3. 个案研究:罗马字母 7.3.1. 校验千位数 7.3.2. 校验百位数 7.4. 使用 {n,m} 语法 7.4.1. ...
- 第十一章 Python 支撑正则表达式处理的re模块
re模块是Python中支持正则表达式处理的模块,老猿学了之后,发现这部分内容太多,要表述清楚需要开单章才能写清楚,但老猿觉得re模块的使用对多数人来说要通过教程学习去熟练掌握很难,需要经常接触练习加 ...
- [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】
[python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...
- Python 进阶 - 正则表达式
1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...
- python使用正则表达式文本替换
2D客户端编程从某种意义上来讲就是素材组织,所以,图片素材组织经常需要批量处理,python一定是最佳选择,不管是win/linux/mac都有一个简单的运行环境 举两个应用场景: 如果不是在某个文件 ...
- python的正则表达式 re
python的正则表达式 re 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以是Unicode字符,这点不用担心,python会处理地和Ascii字符一 ...
- Python之正则表达式(re模块)
本节内容 re模块介绍 使用re模块的步骤 re模块简单应用示例 关于匹配对象的说明 说说正则表达式字符串前的r前缀 re模块综合应用实例 正则表达式(Regluar Expressions)又称规则 ...
- Python:正则表达式详解
正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,作为一个爬虫工作者,每天和字符串打交道,正则表达式更是不可或缺的技能,正则表达式的在不同的语言中使用方式可能 ...
- 【Python】正则表达式纯代码极简教程
<Python3正则表达式>文字版详细教程链接:https://www.cnblogs.com/leejack/p/9189796.html ''' 内容:Python3正则表达式 日期: ...
随机推荐
- python3下搜狗AI API实现
1.背景 a.搜狗也发布了自己的人工智能 api,包括身份证ocr.名片ocr.文本翻译等API,初试感觉准确率一般般. b.基于python3. c.也有自己的签名生成这块,有了鹅厂的底子,相对写起 ...
- Python之格式化输出,初始编码以及运算符
一.题型 1.使用while循环输入 1 2 3 4 5 6 8 9 10 count = 0 while count < 10: count += 1 #count = count + ...
- php程序报错:PHP Core Warning/cannot open shared object file: No such file or directory
今天开发调试程序的时候报错了,现象是有时候刷新会出现如下图: 这种主要是找不到共享库文件,即.so文件,网上主要有3种解决方法: 1. 用ln将需要的so文件链接到/usr/lib或者/lib这两个默 ...
- Python_fullstack_test1
1.执行Python脚本的两种方式 使用交互式的带提示符的解释器或使用源文件 2.简述位.字节的关系 位是计算机中最小计量单位,用bit表示 字节是计算机中最小存储单位,用Byte表示 1字节=8位, ...
- [LeetCode] Brick Wall 砖头墙壁
There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The b ...
- linux必知必会命令
- Ajax/XHR/HTTP/jQuery Ajax
Ajax即通过XHR API使用js发起的异步网络请求,它不会导致页面刷新,因此是现代Web App的关键技术. HTTP协议是Web开发中最重要的网络协议,HTTP协议详细规定了请求和响应报文. 请 ...
- Java IO(三)
在Java IO提供的类中,除了前面介绍的RandomAccessFile类之外,还有一系列的io操作类. 主要分为两大类.字符流和字节流.关系图如下: 在Java IO的操作中,很好的体现了Java ...
- 利用 pyspider 框架抓取猫途鹰酒店信息
利用框架 pyspider 能实现快速抓取网页信息,而且代码简洁,抓取速度也不错. 环境:macOS:Python 版本:Python3. 1.首先,安装 pyspider 框架,使用pip3一键安装 ...
- 洛谷3794 签到题IV
题目描述 给定一个长度为n的序列$a_1,a_2...a_n$,其中每个数都是正整数. 你需要找出有多少对(i,j),$1 \leq i \leq j \leq n$且$gcd(a_i,a_{i+1} ...