Search code examples
phpregexpreg-replacepreg-replace-callback

PHP regex to replace 1st line with 2nd line after every empty line


Is it possible to use PHP preg_replace to get the value of each line and replace it with the value of the next line? For example:

id "text 1"
str ""

id "text 2"
str ""

id "text 6"
id_p "text 6-2"
str[0] ""
str[1] ""

Results in

id "text 1"
str "text 1"

id "text 2"
str "text 2"

id "text 6"
id_p "text 6-2"
str[0] "text 6"
str[1] "text 6-2"

I use regex but I could not do this one and I am not sure if it's possible or not only with regex.

Any help or guidance is appreciated.


Solution

  • Match the blocks capturing the values inside id and id_p with this regex:

    '~^id\h+"(.*)"(?:\Rid_p\h+"(.*)")?(?:\Rstr(?:\[\d])?\h*"")+$~m'
    

    Pass these blocks to the preg_replace_callback callback method, and replace the str "" and str[1] "" with the first capturing group value and str[1] "" with the second capturing group value.

    Use

    $re = '~^id\h+"(.*)"(?:\Rid_p\h+"(.*)")?(?:\Rstr(?:\[\d])?\h*"")+$~m'; 
    $str = "id \"text 1\"\nstr \"\"\n\nid \"text 2\"\nstr \"\"\n\nid \"text 3\"\nstr \"\"\n\nid \"text 4\"\nstr \"\"\n\nid \"text 5\"\nstr \"\"\n\nid \"text 6\"\nid_p \"text 6-2\"\nstr[0] \"\"\nstr[1] \"\""; 
    $result = preg_replace_callback($re, function($m){
        $loc = $m[0];
        if (isset($m[2])) {
            $loc = str_replace('str[1] ""','str[1] "' . $m[2] . '"', $loc);
        }
        return preg_replace('~^(str(?:\[0])?\h+)""~m', "$1\"$m[1]\"",$loc);
    }, $str);
    
    echo $result;
    

    See this PHP demo