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正则表达式 日期: ...
随机推荐
- PHP环境配置(1)
Apache下载 Apache下载地址:http://httpd.apache.org/download.cgi 第一步:点击Files for Microsoft Windows 第二步:点击Apa ...
- python2 当中 遇到 UnicodeDecodeError UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 37: ordinal not in range(128)
使用python2 总是遇到 UnicodeDecodeErrorUnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in positio ...
- 判断ssh远程命令是否执行结束
注:这是一个没什么鸟用的功能.不过也算是一种拓展. 通常在那些"一键化部署"的shell脚本中,可能需要使用ssh执行远程命令来实现一些简单的自动化,这些远程命令可能需要执行一段时 ...
- Mysql中autocommit的用法
定义 Mysql文档原文:SET autocommit disables or enables the default autocommit mode for the current session. ...
- 最小二乘法多项式拟合的Java实现
背景 由项目中需要根据一些已有数据学习出一个y=ax+b的一元二项式,给定了x,y的一些样本数据,通过梯度下降或最小二乘法做多项式拟合得到a.b,解决该问题时,首先想到的是通过spark mllib去 ...
- Python中的上下文管理器和with语句
Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...
- 六,前端---viewport
移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域,再具体一点,就是浏览器上用来显示网页的那部分区域,但viewport又不局限于浏览器可视区域的大小,它可能比浏览器的可视区 ...
- [Codeforces 864E]Fire
Description Polycarp is in really serious trouble — his house is on fire! It's time to save the most ...
- bzoj 3214: [Zjoi2013]丽洁体
Description 平时的练习和考试中,我们经常会碰上这样的题:命题人给出一个例句,要我们类比着写句子.这种往往被称为仿 写的题,不单单出现在小学生的考试中,也有时会出现在中考中.许多同学都喜欢做 ...
- [BZOJ]4199: [Noi2015]品酒大会(后缀数组+笛卡尔树)
Time Limit: 10 Sec Memory Limit: 512 MB Description Input Output Sample Input 10 ponoiiipoi 2 1 4 7 ...