如何循环、匹配和替换?

How to loop through, match and replace?

我有多个带有相同大括号的字符串我想将它们替换为动态的如果我得到计数​​为 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"] 的新值替换, 其次将 {{TWO}} 替换为新值等等。

您的代码存在一些问题,您需要确保 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 注入问题。

在每场比赛的循环中,我建议您使用 str_replace:

而不是使用 preg_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);
} 

您可以通过在一个查询中获取所有替换值来大大简化您的代码:

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

我们可能希望在这里设计的表达式可以是以下之一:

({{)(.+?)(}})

仅使用捕获组 ()

DEMO 1


(?:{{)(.+?)(?:}})

这里我们可以使用 non-capturing 组 (?:),如果我们不想保留 {{}}

DEMO 2

然后,我们可以简单地做我们想做的preg_replace

测试

$re = '/(?:{{)(.+?)(?:}})/m';
$str = '{{ONE}} {{TWO}} {{THREE}} {{FOUR}} {{FIVE}} {{SIX}}';
$subst = '';

$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