Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

214
Views
Loop through preg_match_all result

I am trying to loop through the result of preg_match_all() and to replace the matches.

What I am trying to achieve is to extract all the occurrences in a text that is in between curly brackets with a dollar sign in front, and then create a <span> with an id that is the content within the curly brackets.

So in the example below from the text "Working from ${spa_open_time} to ${spa_close_time} every day", I should extract ${spa_open_time} and ${spa_close_time} and replace them in the text with a <span>.

The expected result

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

Here is the code I came up with so far

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

And the current result is

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

I am doing something wrong but I cannot figure out what's the problem. Here is the code in action http://sandbox.onlinephpfunctions.com/code/31894399fd981fb791c587fa04c68581c4945b6d

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

I've modified your regexp to return the strings to search for (e.g. "${spa_open_time}") and the "keys" (e.g. "spa_open_time"). I'm then looping through those arrays concurrently, and generating a pair of search-and-replace strings which I'm applying to $str, which gets modified every time. At the end of the loop, $str contains your results.

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

`

over 4 years ago · Santiago Trujillo Report

0

If you need to make multiple replacements, using preg_replace_callback() is easier and more reliable than looping over the results of a preg_match_all() with str_replace().

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

This returns the result you expect. If there are no matches, the $text string remains as-is.

Here preg_replace_callback both matches all instances of your regular expression, and lets you transform the matches and return them "in-place", without having to separately search/replace over your string. Then, any replacements will happen exactly where they should, which isn't a given with more complex string replacement operations.

over 4 years ago · Santiago Trujillo Report

0

You can use a capture group \${(\w+)}/ around the word characters, which will be returned as the second item of the matches array when using preg_replace_callback.

The full match is the first item in the matches.

Note that you don't have to escape the curly's in the pattern.

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

Output

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

See a PHP demo.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!