如何一一替换所有出现的字符串(循环)

How to replace all occurrences of string one by one (loop)

我有一些子字符串出现 x 次的字符串。我需要一个接一个地替换每个出现的子字符串(不是一步完成),每次替换一个子字符串时,我需要在替换之前将这个子字符串保存到变量中...

完全正确 - 我在 base64 中输入了文本和三张图片。我需要剪切图像的 base64 代码(将其替换为“”)并将此 img base64 代码保存到新文件中并仅回显输入文本而没有 imgs 的 base64 代码...

我尝试了 for 循环、while 循环、函数...但每次它只替换第一次出现的子字符串而不替换其他

我认为每次在循环周期中我都必须保存 $original_string,因为在我的代码中它总是从输入的整个 $original_string 开始。但是我不知道我必须怎么做...

$img_count = substr_count($original_string, "data:image");

for ($i = 0; $i < $img_count; $i++) {
    $img_name = get_string_between($original_string, 'data-filename="', '.');
    $img_base64 = get_string_between($original_string, 'src="', '"');
    $original_string = str_replace($img_base64, '', $original_string);

    $myfile = fopen("../img/clanky/" . $id_noveho_clanku . "/" . $img_name . ".txt", "w") or die("Unable to open file!");
    $txt = $img_base64;
    fwrite($myfile, $txt);
    fclose($myfile);
}
while (strpos($original_string, "data:image") !== false) {
    $img_name = get_string_between($original_string, 'data-filename="', '.');
    $img_base64 = get_string_between($original_string, 'src="', '"');
    $original_string = str_replace($img_base64, '', $original_string);

    $myfile = fopen("../img/clanky/" . $id_noveho_clanku . "/" . $img_name . ".txt", "w") or die("Unable to open file!");
    $txt = $img_base64;
    fwrite($myfile, $txt);
    fclose($myfile);
}

我想要 3 个文件,其中包含图像的 base64 代码和输入的 twxt,但没有此 base64。但是我只有一个文件,而且没有第一次出现的文本。

编辑: 所以,我发现了这个...

我上传了 img "výstřižek.jpg",在我的网络上 img 正确呈现,没有错误。如果我在我的管理站点上看到虚拟主机,我在文件中正确地看到了这个名称,但是如果我通过 filezilla FTP 连接到我的主机服务器并在此 FTP 客户端中打开文件树,我会看到"VýstÃÂiþek3.jpg"。但是为什么??

这里不能post图片,所以我把截图上传到gdrive,请查看,以便更好地了解实际问题 https://drive.google.com/open?id=1OQn-L1xePo6o1I6U7mmvZbxiEOBhPLvp

是的,您的代码总是 returns 第一个结果,因为它总是从字符串的开头开始匹配,您应该删除已经处理过的部分以使其工作或使用偏移量在每个迭代中开始搜索:从 0 开始,在删除数据之前,使用它的位置作为下一个偏移量。然后,您必须将其传递给 get_string_between 函数以限制搜索。

但由于您的原始字符串实际上是 html,我建议使用一些 html 解析库来避免属性顺序不同、可能的转义问题等问题。这解决方案使用默认情况下应启用的 DOM extension

$doc = new DOMDocument();
// Treat the string as a frament and do not add a DOCTYPE or mandatory tags 
$doc->loadHTML(mb_convert_encoding($original_string, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);

// Get all images
$imgs = $doc->getElementsByTagName('img');

foreach ($imgs as $img) {
    $src = $img->getAttribute('src');
    $name = $img->getAttribute('data-filename');

    // Check if it contains base64 data and a filename
    if (false !== mb_strpos($src, 'data:image') && "" !== $name) {
        $data = mb_substr($src, strpos($src, ',') + 1); // Data start
        $img->setAttribute('src', mb_str_replace($data, '', $src)); // Remove data

        $name = mb_substr($name, 0, strrpos($name, '.'));
        // Save the image to disk
        $path = "../img/clanky/${id_noveho_clanku}/${name}.txt";
        file_put_contents($path, $data);            
    }
}

// Get the HTML with the data removed
$parsed = $doc->saveHTML($doc);

Demo on 3v4l.org