使用PHP的preg_match_all替换文本

huangapple go评论72阅读模式
英文:

Replace text with preg_match_all using PHP

问题

现在字符串是:

产品标题是 [title],价格是 [price],此产品链接是 

还有一个名为 $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>产品是 Infaillible Full Wear327 Cashm,价格是 10.49,此产品链接是 https://www.farmaeurope.eu/infaillible-full-wear327-cashm.html</pre>

结果是可以的,但它移除了实际的文本,即 title, price link

英文:

I have this string:

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

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

答案1

得分: 2

这不是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]

另一种无需使用正则表达式的方法(因为你正在寻找字面字符串):

$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][3]
英文:

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

答案2

得分: 1

我不知道你在尝试做什么,但看起来这完全复杂化了。以下是一个简单的解决方案,带有注释:

$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 
'; preg_match_all($pattern, $optimization_prompt, $matches); // 遍历完整匹配 foreach($matches[0] as $match) { // 移除数组键的括号 $product_key = trim($match, '[]'); // 如果产品键可用,用它替换文本 $optimization_prompt = str_replace($match, $get_product[$product_key] ?? '', $optimization_prompt); } // 结果: The product title is answer and the price is 666 and this product link is https://stackoverflow.com echo $optimization_prompt;
英文:

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

答案3

得分: 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' => '>&#163;10000.99<', 
                'link' => '>http:stackoverflow.com<'
    ];
$optimization_prompt = 'The product title is [title] and the price is [price] and this product link is 
'
;
$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 >&#163;10000.99< and this product link is >http:stackoverflow.com<
英文:

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] =&gt; Array
        (
            [0] =&gt; [title]
            [1] =&gt; [price]
            [2] =&gt; 
) [1] =&gt; Array ( [0] =&gt; title [1] =&gt; price [2] =&gt; link ) )

So you can simplify the code to

$get_product = [&#39;title&#39; =&gt; &#39;&gt;This is a TITLE&lt;&#39;, 
                &#39;price&#39; =&gt; &#39;&gt;&#163;10000.99&lt;&#39;, 
                &#39;link&#39; =&gt; &#39;&gt;http:stackoverflow.com&lt;&#39;
    ];
$optimization_prompt = &#39;The product title is [title] and the price is [price] and this product link is 
&#39;; $pattern = &#39;/\[(.*?)\]/&#39;; preg_match_all($pattern, $optimization_prompt, $matches); print_r($matches); foreach( $matches[0] as $i =&gt; $replace ) { $optimization_prompt = str_replace( $replace, $get_product[$matches[1][$i]], $optimization_prompt); } echo $optimization_prompt;

And the result is

The product title is &gt;This is a TITLE&lt; and the price is &gt;&#163;10000.99&lt; and this product link is &gt;http:stackoverflow.com&lt;

</details>



# 答案4
**得分**: 0

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

<?php

$optimization_prompt = ''The product title is [title] and the price is [price] and this product link is

';
$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:
WITHOUT Replace -title-: :
WITHOUT Replace -price-: :
WITHOUT Replace -link-: :
The product is TITLE and the is PRICE and this product is LINK


<details>
<summary>英文:</summary>

Adding some debug lines should help:

<?php

$optimization_prompt = 'The product title is [title] and the price is [price] and this product link is

';
$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:
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`.

</details>



huangapple
  • 本文由 发表于 2023年3月7日 19:59:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75661713.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定