使用PHP将文本替换为preg_match_all

svmlkihl  于 2023-03-11  发布在  PHP
关注(0)|答案(4)|浏览(150)

我有这样的字符串:

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

我有一个叫做$get_product的变量,它包含了关联数组
现在,我想用$get_product[xxx]变量键替换字符串中的**[xxx]**。

$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);
            }
        }
    }
}

它返回我:

<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>

结果是好的,但它删除了名为标题,价格链接的实际文本

szqfcxe2

szqfcxe21#

这不是preg_match_all的工作,而是preg_replace_callback的工作(这是一个替换任务,是或不是?)

$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
该模式使用捕获组(捕获组1)提取方括号中的内容。preg_replace_callback的第二个参数是回调函数,用于测试捕获的内容$m[1]是否作为数组$get_product中的键存在,并返回相应的值或完全匹配的$m[0]
完全不使用regex的另一种方法(因为您要查找文字字符串):

$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

y53ybaqx

y53ybaqx2#

我不知道你想做什么,但是看起来太复杂了。下面是一个简单的解决方案:

$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;
drkbr07n

drkbr07n3#

如果查看第一个preg_match_all()的结果,您会发现$matches数组中包含了所需的所有内容
$matches阵列

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

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

)

所以你可以简化代码

$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;

结果是

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

gdx19jrr4#

添加一些调试行应该会有所帮助:

<?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;

输出:

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

这里:WITHOUT Replace -title-: :表示-之间的文本替换为:之间的文本,从而有效地删除了文本title

相关问题