1

I have this string:

The product title is [title] and the price is [price] and this product link is [link]

and I have a variable called $get_product whch contain associated array.

Now, I want to replace [xxx] from the string with the $get_product[xxx] variable key. What I am doing this:

$pattern = '/\[(.*?)\]/';
preg_match_all($pattern, $optimization_prompt, $matches);

if( $matches ) {
    foreach( $matches as $key => $match ) {
        for( $i = 0; $i < count($match); $i++ ) {
            if( preg_match_all($pattern, $match[$i], $matches)  ) {
                // with bracket 
                $remove_bracket         = trim( $match[$i], '[]');
                $optimization_prompt    = str_replace( $match[$i], isset( $get_product[$remove_bracket] ) ? $get_product[$remove_bracket] : '', $optimization_prompt);
            } else {
                // Without bracket
                $remove_bracket         = trim( $match[$i], '[]');
                $optimization_prompt    = str_replace( $match[$i], '', $optimization_prompt);
            }
        }
    }
}

Its returning me:

<pre>The product  is  Infaillible Full Wear327 Cashm and the  is  10.49  and this product  is  https://www.farmaeurope.eu/infaillible-full-wear327-cashm.html</pre>

The result is okay but its removed the actual text called title, price link

5
  • Why do you remove brackets, and then ask why the actual text is replaced ? Commented Mar 7, 2023 at 12:04
  • I remove the bracket to get the bracket value to get the key value from the $get_product variable Commented Mar 7, 2023 at 12:07
  • Like this $get_product[$remove_bracket] to get the value from the varilable which I want to replace. Commented Mar 7, 2023 at 12:08
  • Ok, let me rephrase, what are you replacing in the else branch? (The one with the comment "without bracket") ? Commented Mar 7, 2023 at 12:15
  • @Luuk i was thinking something else but forget this else block. My overally goal is to replace the [xxx] with the $get_product[xxx] value. Commented Mar 7, 2023 at 12:20

4 Answers 4

2

It isn't a job for preg_match_all but for preg_replace_callback (it's a replacement task yes or not?).

$get_product = ['title' => 'theTitle', 'price' => 45, 'link' => 'https://thelink.com'];

$result = preg_replace_callback(
    '~\[([^][]+)]~',
    fn($m) => $get_product[$m[1]] ?? $m[0],
    $optimization_prompt
);

demo

The pattern uses a capture group (capture group 1) to extract content between square brackets. The second parameter of preg_replace_callback is the callback function that tests if the captured content $m[1] exists as key in the array $get_product and returns the corresponding value or the full match $m[0].


Other way without regex at all (since you are looking for literal strings):

$get_product = ['title' => 'theTitle', 'price' => 45, 'link' => 'https://thelink.com'];

$result = str_replace(
    array_map(fn($k) => "[$k]", array_keys($get_product)),
    $get_product,
    $optimization_prompt
);

demo

Sign up to request clarification or add additional context in comments.

Comments

1

I don't know what you're trying to do there, but it's totally overcomplicated it seems. Here's a simple solution w/ comments:

$pattern = '/\[.*?\]/';
$get_product = ['title' => 'answer', 'price' => 666, 'link' => 'https://stackoverflow.com'];
$optimization_prompt = 'The product title is [title] and the price is [price] and this product link is [link]';
preg_match_all($pattern, $optimization_prompt, $matches);

// Cycle through full matches
foreach($matches[0] as $match) {
    // Remove the brackets for the array key
    $product_key = trim($match, '[]');
    
    // If product key available, replace it in the text
    $optimization_prompt = str_replace($match, $get_product[$product_key] ?? '', $optimization_prompt);
}

// Result: The product title is answer and the price is 666 and this product link is https://stackoverflow.com
echo $optimization_prompt;

1 Comment

WOW, Great. Its seems easier version.
1

If you look at the result of your first preg_match_all() you will see you have all you need in the $matches array

The $matches array

Array
(
    [0] => Array
        (
            [0] => [title]
            [1] => [price]
            [2] => [link]
        )

    [1] => Array
        (
            [0] => title
            [1] => price
            [2] => link
        )

)

So you can simplify the code to

$get_product = ['title' => '>This is a TITLE<', 
                'price' => '>£10000.99<', 
                'link' => '>http:stackoverflow.com<'
    ];
$optimization_prompt = 'The product title is [title] and the price is [price] and this product link is [link]';

$pattern = '/\[(.*?)\]/';

preg_match_all($pattern, $optimization_prompt, $matches);
print_r($matches);

foreach( $matches[0] as $i => $replace ) {
    $optimization_prompt = str_replace( $replace, $get_product[$matches[1][$i]], $optimization_prompt);
}

echo $optimization_prompt;

And the result is

The product title is >This is a TITLE< and the price is >£10000.99< and this product link is >http:stackoverflow.com<

Comments

0

Adding some debug lines should help:

<?php

$optimization_prompt = 'The product title is [title] and the price is [price] and this product link is [link]';
$get_product = [ "title"=>"TITLE", "price"=>"PRICE", "link"=>"LINK"];

$pattern = '/\[(.*?)\]/';
preg_match_all($pattern, $optimization_prompt, $matches);

if( $matches ) {
    foreach( $matches as $key => $match ) {
        for( $i = 0; $i < count($match); $i++ ) {
            if( preg_match_all($pattern, $match[$i], $matches)  ) {
                // with bracket 
                $remove_bracket         = trim( $match[$i], '[]');
                print "WITH Replace -$match[$i]-:". (isset( $get_product[$remove_bracket] ) ? $get_product[$remove_bracket] : '').":" .PHP_EOL;
                $optimization_prompt    = str_replace( $match[$i], isset( $get_product[$remove_bracket] ) ? $get_product[$remove_bracket] : '', $optimization_prompt);
            } else {
                // Without bracket
                $remove_bracket         = trim( $match[$i], '[]');
                print "WITHOUT Replace -$match[$i]-: ". '' .":".PHP_EOL;
                $optimization_prompt    = str_replace( $match[$i], '', $optimization_prompt);
            }
        }
    }
}

print $optimization_prompt;

output:

WITH Replace -[title]-:TITLE:
WITH Replace -[price]-:PRICE:
WITH Replace -[link]-:LINK:
WITHOUT Replace -title-: :
WITHOUT Replace -price-: :
WITHOUT Replace -link-: :
The product  is TITLE and the  is PRICE and this product  is LINK

Here: WITHOUT Replace -title-: : means that the text between - is replaced by the text between :, effectively removing the text title.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.