У меня есть несколько строк с одинаковыми фигурными скобками. Я хочу заменить их как динамические, если я получу счет как 1, тогда мне нужно заменить первое вхождение, если считать как 2, то замените второе вхождение, пока не будет выполнено условие.
<?php
include_once("con.php");
$db = new Da();
$con = $db->con();
$String = "{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}";
$Count = 1;
if (preg_match_all("/\{\{[^{}]+\}\}/", $lclString, $matches)) {
foreach ($matches[0] as $match) {
$Count++;
$Query = "SELECT link FROM student WHERE linkVal = '".$match."'";
$Result = $con->query($Query);
if ($row = $Result->fetch(PDO::FETCH_ASSOC)) {
$NewValue = preg_replace("/\{\{[^{}]+\}\}/", $row["link"], $String);
}
}
echo json_encode($NewValue);
}
?>
При первом появлении {{ONE}} следует заменить новым значением на $row["link"], Во-вторых, замените {{ДВА}} на новое значение и т. д.
проверю ваше предложение
Тот заменил только один матч.
Используйте его внутри цикла вместо preg_replace






Есть несколько проблем с вашим кодом, вам нужно убедиться, что переменная в preg_match_all() является строкой, которую вы пытаетесь найти.
Но основная проблема заключается в замене детали. Вам нужно заменить текущее значение совпадения ($match) и заменить его новой строкой — в настоящее время вы всегда заменяете новое совпадение в исходной строке. Здесь я создаю $NewValue из исходной строки и продолжаю заменять значения в ней...
if (preg_match_all("/\{\{[^{}]+\}\}/", $String, $matches)) {
$NewValue = $String;
foreach ($matches[0] as $match) {
$Count++;
$Query = "SELECT link FROM student WHERE linkVal = '".$match."'";
$Result = $con->query($Query);
if ($row = $Result->fetch(PDO::FETCH_ASSOC)) {
$NewValue = preg_replace("/".preg_quote($match)."/",
$row["link"], $NewValue);
}
}
echo json_encode($NewValue);
}
Вам также следует изучить возможность использования подготовленных операторов, поскольку в настоящее время вы можете столкнуться с проблемами SQL-инъекций.
произошла только одна замена.
заменив две строки одной и той же заменой, например {{ONE}} {{TWO}} заменив обе на 1 и 1.
Можете ли вы показать, какое значение содержится в linkVal и link в таблице student? (Поскольку значение $match будет {{ONE}})
В цикле для каждого совпадения вместо использования preg_replace я предлагаю вам использовать str_replace:
if (preg_match_all("/\{\{[^{}]+\}\}/", $lclString, $matches)) {
$NewValue = $String;
foreach ($matches[0] as $match) {
$Count++;
$Query = "SELECT link FROM student WHERE linkVal = '".$match."'";
$Result = $con->query($Query);
if ($row = $Result->fetch(PDO::FETCH_ASSOC)) {
$NewValue = str_replace($match, $row["link"], $NewValue);
// ^^^^^^^^^^^^^^^^^^
}
}
echo json_encode($NewValue);
}
Помимо использования str_replace - не уверен, есть ли разница между этим и моим ответом.
@Michael: Каков результат echo json_encode($NewValue); и чего вы ожидаете?
@NigelRen: Конечно, это единственная разница, я прокомментировал вопрос, прежде чем опубликовать его в качестве ответа, поэтому я разместил его через 2 минуты после вас.
Но ваш комментарий включает в себя первоначальный недостаток постоянной замены в исходной строке.
@NigelRen: я сосредоточился на том, как правильно заменить, затем исправил ошибку при ответе, и str_replace намного эффективнее, чем preg_replace
способный заменить единичное вхождение.
@Michael: Вставьте отладку в свой код, что содержит $row["link"] (например)
$row["link"] содержит, например, ABC, XYZ, PQR, HGK и т. д.
В первом случае я хочу заменить ABC, а затем 2-й XYZ, 3-й PQR как петли.
@Michael: добавьте больше отладки, напечатайте $match, $row["link"], $NewValue до и после замены, ...
Вы можете значительно упростить свой код, извлекая все значения замены в одном запросе:
$String = "{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}";
if (preg_match_all("/\{\{[^{}]+\}\}/", $String, $matches)) {
$Query = "SELECT linkVal, link FROM student WHERE linkVal IN('".implode("','", $matches[0])."')";
$Result = $con->query($Query);
if ($rows = $Result->fetchAll(PDO::FETCH_ASSOC)) {
$NewValue = str_replace(array_column($rows, 'linkVal'), array_column($rows, 'link'), $String);
}
echo json_encode($NewValue);
}
@Michael Майкл, вы знаете, возвращает ли запрос какие-либо результаты? Можно var_dump($rows);?
запрос, возвращающий несколько разных результатов
@Michael, если запрос возвращает результаты, str_replace должен работать - вот пример: 3v4l.org/ch9HV
@Майкл, извините, только что понял, что у меня опечатка в коде. Можете ли вы попробовать еще раз (я отредактировал ответ)
@Майкл, не могли бы вы сообщить мне, что вы получаете с var_dump($rows);? Если бы я мог видеть это, я уверен, что мог бы решить проблему быстро.
на var_dump() я получаю два разных изображения <img src = "локальный/image1.png"> <img src = "локальный/image2.png">
Происходит вторая замена.
Происходит только последняя замена.
@Michael, изображения, на которые вы ссылаетесь, находятся на вашем локальном сервере, поэтому я их не вижу. Но похоже, что вы нашли ответ, так что не беспокойтесь об этом.
Выражение, которое мы могли бы создать здесь, может быть похоже на одно из следующих:
({{)(.+?)(}})
который использует только группы захвата ().
(?:{{)(.+?)(?:}})
и здесь мы можем использовать незахватывающие группы (?:), если мы не хотим сохранять {{ и }}.
Тогда мы могли бы просто сделать preg_replace то, что хотели сделать.
$re = '/(?:{{)(.+?)(?:}})/m';
$str = '{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}';
$subst = '$1';
$result = preg_replace($re, $subst, $str);
echo "The result of the substitution is ".$result;
Вы можете использовать preg_replace_callback для повторения ваших совпадений.
например
$str = "{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}";
$replaced = preg_replace_callback('/{{([^{}]*)}}/', function($match) {
// $match[1] contains the current match (first capture group) e.g. ONE
// return your replacement for the current match, e.g. reversed string ENO
return strrev($match[1]);
}, $str);
echo $replaced;
Вывод будет ENO OWT EERHT RUOF EVIF XIS
Как насчет:
$NewValue = str_replace($match, $row["link"], $String);