最近在项目中遇到一个问题,就是需要采用正则匹配一些疑似暗链和挂马的HTML代码,而公司的老大给的正则表达式有的地方写的不够严谨,导致在匹配的时候发生卡死的现象,而后面的逻辑自然无法执行了。虽然用正则表达式来判断暗链和挂马可能不那么准确或者行业内很少有人那么做,但是本文不讨论如何使用正确的姿势判断暗链挂马,只关注与正则超时的处理。

在使用正则表达式的时候,如果正则写的太糟糕,所消耗的时间是惊人的,并且有可能会一直回溯,而产生卡死的现象,所以一般的大型公司都会有专门的人来对正则进行优化,从而提高程序效率。一般来说如果可能的话不要让用户来输入正则进行匹配。但是现在既没有专门的人进行正则的优化,本人也对正则了解的不够,所以只能从另外的角度来考虑处理超时的问题。

首先我想到的方法是另外开启一个线程来进行匹配,而在主线程中进行等待,如果发现子线程在规定的时间内没有返回就kill掉子线程。这也是一个方案,但是我现在要介绍另外一种方案,该方案来自我在网上看到的一篇博客.

博客地址

该博客给出了另外一种办法,就是采用信号的方式,在正则匹配之前定义一个信号,并规定触犯时间和处理的函数,如果在规定时间内程序没有结束那么触发一个TimeoutError的异常,而主线程收到这个异常时就会中断执行,并处理这个异常,这样就从正则匹配中解脱出来,达到了我们要的结果。这个方法有两个不足之处:

  1. 信号这个东西是Linux独有的,在Windows下不适用
  2. 信号只能在主线程中使用,而如果在子线程中进行正则匹配,那么这个方法就不适用

我的项目正在运行在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处理正则表达式超时的办法的更多相关文章

  1. python study - 正则表达式

    第 7 章 正则表达式 7.1. 概览 7.2. 个案研究:街道地址 7.3. 个案研究:罗马字母 7.3.1. 校验千位数 7.3.2. 校验百位数 7.4. 使用 {n,m} 语法 7.4.1. ...

  2. 第十一章 Python 支撑正则表达式处理的re模块

    re模块是Python中支持正则表达式处理的模块,老猿学了之后,发现这部分内容太多,要表述清楚需要开单章才能写清楚,但老猿觉得re模块的使用对多数人来说要通过教程学习去熟练掌握很难,需要经常接触练习加 ...

  3. [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】

    [python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...

  4. Python 进阶 - 正则表达式

    1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...

  5. python使用正则表达式文本替换

    2D客户端编程从某种意义上来讲就是素材组织,所以,图片素材组织经常需要批量处理,python一定是最佳选择,不管是win/linux/mac都有一个简单的运行环境 举两个应用场景: 如果不是在某个文件 ...

  6. python的正则表达式 re

    python的正则表达式 re 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以是Unicode字符,这点不用担心,python会处理地和Ascii字符一 ...

  7. Python之正则表达式(re模块)

    本节内容 re模块介绍 使用re模块的步骤 re模块简单应用示例 关于匹配对象的说明 说说正则表达式字符串前的r前缀 re模块综合应用实例 正则表达式(Regluar Expressions)又称规则 ...

  8. Python:正则表达式详解

    正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,作为一个爬虫工作者,每天和字符串打交道,正则表达式更是不可或缺的技能,正则表达式的在不同的语言中使用方式可能 ...

  9. 【Python】正则表达式纯代码极简教程

    <Python3正则表达式>文字版详细教程链接:https://www.cnblogs.com/leejack/p/9189796.html ''' 内容:Python3正则表达式 日期: ...

随机推荐

  1. JSON(二)——JavaScript中js对象与JSON格式字符串的相互转换

    首先我们来看一下js中JSON格式的字符串 var JSONStr1 = "{\"name\" : \"张三\"}"; 注意以下的写法不是j ...

  2. Linux网络配置(setup)

    新装的Linux系统,想要快捷的网络配置,首选setup命令. 1.设置setup为中文. echo LANG="zh_CN.UTF-8" > /etc/sysconfig/ ...

  3. Python之日志 logging模块

    关于logging模块的日志功能 典型的日志记录的步骤是这样的: 创建logger 创建handler 定义formatter 给handler添加formatter 给logger添加handler ...

  4. Python系列之 - 面向对象(1)

    python是一门面向对象的编程语言,python中的一切均是对象. 有对象就提到类,对象和类就像是儿子和老子的关系,是不可分的一对. 什么是类     类就是具有一些共同特性的事物的统称.好比人类, ...

  5. 菜鸟容易中的招__setattr__

    class Counter: def __init__(self): self.counter = 0 # 这里会触发 __setattr__ 调用 def __setattr__(self, nam ...

  6. Spring(3)——装配 Spring Bean 详解

    装配 Bean 的概述 前面已经介绍了 Spring IoC 的理念和设计,这一篇文章将介绍的是如何将自己开发的 Bean 装配到 Spring IoC 容器中. 大部分场景下,我们都会使用 Appl ...

  7. 谁说深入浅出虚拟机难?现在我让他通俗易懂(JVM)

    1:什么是JVM大家可以想想,JVM 是什么?JVM是用来干什么的?在这里我列出了三个概念,第一个是JVM,第二个是JDK,第三个是JRE.相信大家对这三个不会很陌生,相信你们都用过,但是,你们对这三 ...

  8. UWP中的文件相关操作

    最近开始做UWP开发,图省事儿就把自己之前一个Winform项目的一部分代码拷贝到了新写的UWP项目中来.整出了一些幺蛾子,下面做一个记录. 首先提一个重点就是:UWP里关于文件的操作尽量用Stora ...

  9. java中的多态案例

    多态性实际上有两种: 1.方法的多态性: 1.1方法重载:相同的方法名,会根据传入的参数的类型和个数不同执行不同的方法 1.2方法覆写:同一个方法名称,会根据子类的不同实现不同的功能 2.对象的多态性 ...

  10. openSUSE虚拟机安装并连接Xshell