深度分析正则(pcre)最大回溯/递归限制

深度分析正则(pcre)最大回溯/递归限制

正则表达式是一种描述字符模式的工具,由于其强大的表达能力和广泛的应用场景,成为了数据分析、文本挖掘等领域的重要工具。正则表达式引擎可以进行的匹配步骤是有限的,当模式中包含递归或回溯时,引擎可能会一直重复步骤,导致匹配效率降低,甚至出现崩溃等问题。

为了避免这种状况,正则表达式引擎实现了最大回溯/递归限制,即“PCRE recursion limit”和“PCRE backtracking limit”参数。

PCRE为Perl Compatible Regular Expressions(Perl兼容正则表达式),是一个库,由C语言编写。

PCRE Recursion Limit

PCRE Recursion Limit用来限制正则表达式中递归调用的深度,避免无限递归,消耗过多的系统资源并导致应用程序崩溃。缺省值是100000,也就是说当递归调用次数达到100000时程序会停止运行。

PCRE回溯限制

PCRE Backtracking limit用来限制正则表达式的回溯操作的深度,避免重复回溯而导致性能问题和运行程序崩溃。缺省值是1000000,也就是达到1000000次回溯时程序会停止运行。

当超过限制时,PCRE将会返回一个错误:PCRE_ERROR_RECURSIONLIMIT 或 PCRE_ERROR_BACKTRACKLIMIT。通过在调用编译/匹配函数时提供合适的限制,可以避免由于正则表达式中过多的递归或过多的回溯,导致应用程序无响应或崩溃等问题。

示例

假设我们要查找字符串“a”重复出现的字符串,“a”重复的次数不确定,可以使用“/a+ /”正则表达式。

当a的数目比较小的时候,该正则表达式可以很快的匹配成功。然而,当a的数目变大时,匹配就会花费更多的时间。这是因为正则表达式引擎在执行回溯过程中,不断的试图寻找更多的匹配结果。这就是“回溯/递归”错误/问题。

可以通过限制匹配的递归深度和回溯深度来解决这个问题。

下面是一个具体的例子。我们的目标是在由三组 a 组成,中间由连字符 - 分割的字符串中查找匹配串。

$input = 'aaa-bbbbb-aaaaaaa';
echo preg_match('/((a+)+)-((a+)+)-((a+)+)/', $input);  // 输出1

//增加限制
echo preg_match('/((a+){1,' . ini_get("pcre.recursion_limit") . '})-((a+){1,' . ini_get("pcre.recursion_limit") . '})-((a+){1,' . ini_get("pcre.recursion_limit") . '})/', $input); // 输出1

//触发回溯限制
$input = 'aaaaaaaaaaaaaaaaaaaaaa-x';
echo preg_match('/((a+)+)-x/', $input); // 出现回溯错误

//增加限制
echo preg_match('/((a+){1,' . ini_get("pcre.backtrack_limit") . '})+-x/', $input); // 处理正常

上面的这个例子是PHP实现的,但其他语言的实现也会有同样的问题和限制。在编写正则表达式时,应该谨慎地使用回溯和递归,以避免漏洞和性能问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深度分析正则(pcre)最大回溯/递归限制 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Android实现通讯录效果——获取手机号码和姓名

    Android实现通讯录效果——获取手机号码和姓名 在Android应用中实现通讯录效果,可以通过以下步骤获取手机号码和姓名。 步骤一:添加权限 首先,在AndroidManifest.xml文件中添加以下权限: <uses-permission android:name=\"android.permission.READ_CONTACTS\…

    other 2023年9月6日
    00
  • xp显示文件扩展名 多种方法显示XP文件扩展名

    XP显示文件扩展名攻略 在Windows XP操作系统中,默认情况下,文件的扩展名是隐藏的。然而,有时候我们需要显示文件的扩展名,以便更好地管理和识别文件。下面是几种方法来显示XP文件扩展名的攻略。 方法一:通过文件夹选项显示扩展名 打开“我的电脑”或者任意一个文件夹。 点击菜单栏中的“工具”选项,然后选择“文件夹选项”。 在弹出的“文件夹选项”对话框中,点…

    other 2023年8月5日
    00
  • Spark(四十六):Spark 内存管理之—OFF_HEAP

    Spark(四十六):Spark 内存管理之—OFF_HEAP 在前面的文章中,我们已经对Spark的内存管理机制进行了深入学习和探讨。本篇文章将着重介绍Spark中的OFF_HEAP内存管理机制。 什么是OFF_HEAP OFF_HEAP是指在应用程序的堆之外,开辟一块专门用来存放JVM堆外内存的空间。相比于传统的JVM堆内存,OFF_HEAP有以下几个优…

    其他 2023年3月28日
    00
  • PowerBuilder学习笔记之3应用对象

    PowerBuilder学习笔记之3应用对象的完整攻略 PowerBuilder是一种流行的客户端开发工具,可以用于开发Windows应用程序和Web应用程序。应用对象是PowerBuilder中的一个重要概念,它是一种可重用的代码模块,可以在应用程序中多次使用。本文将为您提供一份完整攻略,介绍如何使用PowerBuilder应用对象,并提供两个示例说明。 …

    other 2023年5月5日
    00
  • 10分钟搞定让你困惑的 Jenkins 环境变量过程详解

    下面是“10分钟搞定让你困惑的 Jenkins 环境变量过程详解”的完整攻略。 什么是 Jenkins 环境变量? 在 Jenkins 中,环境变量代表着许多有用的信息,如构建号,构建时间等。使用环境变量可以帮助您更方便地编写构建脚本。 Jenkins 环境变量的使用 Jenkins 环境变量是由插件“EnvInject”提供支持,安装并启用此插件即可使用。…

    other 2023年6月27日
    00
  • tomcat 启动时卡住问题排查及解决方法

    当使用Tomcat启动Web应用程序时,有可能会遇到启动过程中卡住的情况。这篇攻略将带您分步骤排查及解决tomcat启动时卡住问题。 问题排查 1. 检查Tomcat日志 Tomcat启动时通常会向控制台输出一些信息和日志,因此可以打开控制台,查看Tomcat的启动日志信息。如果Tomcat由于某些原因被卡住了,日志中可能会提示错误信息。 2. 检查操作系统…

    other 2023年6月26日
    00
  • WPF基于物理像素绘制图形

    下面就为您详细讲解一下“WPF基于物理像素绘制图形”的攻略。 什么是WPF基于物理像素绘制图形 WPF基于物理像素绘制图形即使用真实的硬件像素来表示每个屏幕像素,而不是使用虚拟像素。在WPF中,每个控件的大小、位置和边框等都是以真实像素为单位。这种方式相对于以前的GDI和GDI+技术,可以更好地适应高分辨率屏幕,在显示高清图形时有更好的表现。 WPF基于物理…

    other 2023年6月26日
    00
  • Android 网络请求框架Volley实例详解

    Android 网络请求框架Volley实例详解 Volley是一种用于Android应用程序的网络请求框架,它提供了简单且强大的API,用于处理网络请求和响应。本攻略将详细介绍如何使用Volley进行网络请求,并提供两个示例说明。 步骤1:添加Volley依赖 首先,您需要在您的Android项目中添加Volley库的依赖。在您的项目的build.grad…

    other 2023年8月26日
    00
合作推广
合作推广
分享本页
返回顶部