循环 preg_match_all 结果

Loop through preg_match_all result

我正在尝试遍历 preg_match_all() 的结果并替换匹配项。

我想要实现的是提取前面带有美元符号的大括号之间的文本中出现的所有事件,然后创建一个 <span>,其 id 是其中的内容花括号。

因此在下面的示例中,从文本“每天从 ${spa_open_time} 工作到 ${spa_close_time}”,我应该提取 ${spa_open_time}${spa_close_time} 并在文本中用 <span>.

替换它们

预期结果

Working from <span id="tag_spa_open_time">${spa_open_time}</span> to <span id="tag_spa_close_time">${spa_close_time}</span> every day

这是我到目前为止想出的代码

$text = 'Working from ${spa_open_time} to ${spa_close_time} every day';
$result = preg_match_all('/($\{\w+\})/', $text, $positive_catch);
if ($result > 0) {
    foreach ($positive_catch as $catch) {
        if (is_array($catch)) {
            foreach ($catch as $key => $ivalue) {
                $fvalue = str_replace("${", "", $ivalue);
                $fvalue = str_replace("}", "", $fvalue);
                $replace = '<span id="tag_'.$fvalue.'">'.$ivalue.'</span>';
                $str = str_replace($catch,$replace,$text);
            }
        }
    }
} else {
    $str = $text;
    }
echo $str;

而目前的结果是

Working from <span id="tag_spa_close_time"><span id="tag_spa_close_time">${spa_close_time}</span></span> to <span id="tag_spa_close_time">${spa_close_time}</span> every day

我做错了什么,但我无法弄清楚问题出在哪里。 这是实际的代码 http://sandbox.onlinephpfunctions.com/code/31894399fd981fb791c587fa04c68581c4945b6d

如果您需要进行多次替换,使用 preg_replace_callback() 比使用 str_replace().

循环 preg_match_all() 的结果更容易和更可靠
$text = 'Working from ${spa_open_time} to ${spa_close_time} every day';

$text = preg_replace_callback('/($\{\w+\})/', function($match) {

        // Removing the leading and trailing characters for class name:
        $fvalue = substr($match[1], 2, -1);

        // Returning the match (your $ivalue) wrapped in a span-tag:
        return '<span id="tag_'.$fvalue.'">' . $match[1] . '</span>';
}, $text);

这return是您期望的结果。如果没有匹配项,$text 字符串保持原样。

这里 preg_replace_callback 都匹配您的正则表达式的所有实例,并允许您转换匹配项并 return 它们“就地”,而无需单独 search/replace细绳。然后,任何替换都将准确地发生在它们应该发生的位置,这不是给定的更复杂的字符串替换操作。

我已将您的正则表达式修改为 return 要搜索的字符串(例如“${spa_open_time}”)和“键”(例如“spa_open_time”) .然后我同时循环遍历这些数组,并生成一对搜索和替换字符串,我将其应用于 $str,每次都会修改。在循环结束时,$str 包含您的结果。

$str = $text = 'Working from ${spa_open_time} to ${spa_close_time} every day';
$result = preg_match_all('/$\{(\w+)\}/', $text, $positive_catch);

if ($result > 0) {
    for ( $i=0; $i < sizeof($positive_catch[0]); $i++ ) {
        $search = $positive_catch[0][$i];
        $key = $positive_catch[1][$i];
        $replace = '<span id="tag_' . $key . '">' . $search . '</span>';

        $str = str_replace($search, $replace, $str);
    }
} else {
    $str = $text;
}
echo $str;

`

您可以在单词字符周围使用捕获组 ${(\w+)}/,当使用 preg_replace_callback 时,它将作为 matches 数组的第二项返回。

完整匹配项是匹配项中的第一项。

注意您不必转义模式中的卷曲。

$text = 'Working from ${spa_open_time} to ${spa_close_time} every day';
$text = preg_replace_callback('/${(\w+)}/', function($matches) {
    return sprintf('<span id="tag_%s">%s</span>',$matches[1], $matches[0]);
}, $text);

echo $text;

输出

Working from <span id="tag_spa_open_time">${spa_open_time}</span> to <span id="tag_spa_close_time">${spa_close_time}</span> every day

看到一个PHP demo