提问人:Shibbir 提问时间:3/7/2023 最后编辑:ADysonShibbir 更新时间:3/7/2023 访问量:70
使用 PHP 将文本替换为preg_match_all
Replace text with preg_match_all using PHP
问:
我有这个字符串:
The product title is [title] and the price is [price] and this product link is [link]
我有一个名为 whch 包含相关数组的变量。$get_product
现在,我想用变量键替换字符串中的 [xxx]。我正在做什么:$get_product[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>
结果是可以的,但它删除了称为标题、价格链接的实际文本
答:
0赞
Luuk
3/7/2023
#1
添加一些调试行应该会有所帮助:
<?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
1赞
Destroy666
3/7/2023
#2
我不知道你想在那里做什么,但它似乎完全太复杂了。这是一个带有注释的简单解决方案:
$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;
评论
0赞
Shibbir
3/7/2023
哇,太棒了。它似乎更容易的版本。
1赞
RiggsFolly
3/7/2023
#3
如果你看一下你的第一个结果,你会发现你在数组中拥有了你需要的一切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<
2赞
Casimir et Hippolyte
3/7/2023
#4
这不是一份工作,而是preg_replace_callback
的工作(这是一项替代任务,是还是不是?preg_match_all
$get_product = ['title' => 'theTitle', 'price' => 45, 'link' => 'https://thelink.com'];
$result = preg_replace_callback(
'~\[([^][]+)]~',
fn($m) => $get_product[$m[1]] ?? $m[0],
$optimization_prompt
);
该模式使用捕获组(捕获组 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
);
评论
$get_product[$remove_bracket]
else
[xxx]
$get_product[xxx]