Search code examples
phpregexpreg-replacepreg-replace-callback

How to replace specific numbers (within a length limit) with specific letters?


I am trying to use preg_replace to change numbers to letters, but only numbers wrapped in "" and not more than 7 characters in the substring.

Sample input string:

"3"sca"""co"1"str"0"ctor""r"3"t"0"r"1""locat"5"o"133""0"27""754a49b393c2a0"33"b97"332"cb7"3"c3c07"2""co"1"str"0"ctor""r"3"t"0"

The desired effect is for every qualifying 2 to become d and every qualifying 3 to become e.

These are examples of correct replacements:

  • "3" becomes e
  • "23" becomes de
  • "33" becomes ee
  • "32" becomes de
  • "333223" becomes eeedde

My coding attempt:

$string = preg_replace("/\"322\"+/", "edd", $string);
$string = preg_replace("/\"233\"+/", "dee", $string);
$string = preg_replace("/\"32\"+/", "ed", $string);
$string = preg_replace("/\"23\"+/", "de", $string);
$string = preg_replace("/\"33\"+/", "e", $string);
$string = preg_replace("/\"333\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);
$string = preg_replace("/\"3\"+/", "e", $string);

How can I make all qualifying replacements with one preg_replace call?


Solution

  • Use this regex to find either 2 or 3 between double-quotes from 1 to 7 times

    (?<=\")[23]{1,7}(?=\")

    "233223322" won't be replaced with "deeddeedd" because it has more than 7 characters (9)

    Demo

    Explanation

    [23]{1,7} Either 2 or 3 from 1 to 7 times

    (?<=\") Precedeed by a double-quote

    (?=\") Followed by a double-quote

    Snippet

    $text = '"3"sca"""co"1"str"0"ctor""r"3"t"0"r"1""locat"5"o"133""0"27""754a49b393c2a0"33"b97"332"cb7"3"c3c07"2""co"1"str"0"ct"233223322"or""r"3"t"0"';
    
    $regex = '/(?<=\")[23]{1,7}(?=\")/';
    
    $text = preg_replace_callback($regex, 
        function ($m) {
            switch ($m[0]) {
                case '2': return 'd';
                case '3': return 'e';
                // Add other cases here ...
            }
        },
        $text
    );
    
    echo $text;
    

    Online demo