Skip to content

Unexpected behavior of preg_match #8316

Closed

Description

@great-handsome

Description

The following code:

<?php
$clean_text = "22ABCDE1ABCDE2ABCDE3ABCDE4ABCDE5ABCDESubtotalABCDE1ABCDE11111ABCDE111111ABCDE22222222222222222222222222222222222ABCDE111111111111111ABCDE211111111111111111111111ABCDE111111111111111111111111ABCDE11111111111111111111111111111ABCDE1111111111ABCDE11111111111111ABCDE11111111111111111111111111111111111111111111111111111";

if( preg_match( '/(.*)ABCDE(.*)ABCDE(.*)ABCDE(.*)ABCDE(.*)ABCDE(.*)ABCDESubtotal/',$clean_text, $data_d ))
	print_r($data_d);
else
	echo 'NO';

Resulted in this output:

NO

But I expected this output instead:

Array
(
    [0] => 22ABCDE1ABCDE2ABCDE3ABCDE4ABCDE5ABCDESubtotal
    [1] => 22
    [2] => 1
    [3] => 2
    [4] => 3
    [5] => 4
    [6] => 5
)

If I delete the last char from $clean_text ( or one char from 22222222222222222222222222222222222 ) , preg_match returns TRUE.

I tried on PHP 7.4 and 8.1 , on 2 servers.

PHP Version

PHP 8.1

Operating System

Ubuntu : Linux core 5.3.0-47-generic #39~18.04.1-Ubuntu SMP Mon Apr 6 17:04:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Activity

  1. KapitanOczywisty commented on Apr 7, 2022

    @KapitanOczywisty

    echo preg_last_error_msg(); -> Backtrack limit exhausted
    https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.backtrack-limit

    Good tool for debugging regex: https://regex101.com/

  2. cmb69 commented on Apr 7, 2022

    @cmb69
    Member

    Indeed! This is just a bad regex; very quick fix (using ungreedy matching): https://3v4l.org/DJCKD.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions